resolved conflicts

This commit is contained in:
2025-03-31 03:46:05 +03:00
6454 changed files with 1520539 additions and 9 deletions
@@ -0,0 +1,849 @@
<?php
namespace Modules\PatientFinance\Http\Controllers;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Streamline\Models\ChartOfAccount;
use Streamline\Models\Drug;
use Streamline\Models\EyeGlasses;
use Streamline\Models\EyeGlassesDeposits;
use Streamline\Models\FinancePointTag;
use Streamline\Models\InpatientBill;
use Streamline\Models\InsuranceClaim;
use Streamline\Models\InvestigationDeposit;
use Streamline\Models\OrderedEyeGlasses;
use Streamline\Models\OrderedInvestigation;
use Streamline\Models\OrderedProcedure;
use Streamline\Models\OrderedService;
use Streamline\Models\OrderedSundry;
use Streamline\Models\PatientCategoryInvoice;
use Streamline\Models\ProcedureDeposit;
use Streamline\Models\ServiceDeposit;
use Streamline\Models\Sundry;
use Streamline\Models\SundryDeposit;
use Streamline\Models\Treatment;
use Streamline\Models\TreatmentDeposits;
use Streamline\Services\WardManagement\InpatientFinanceService;
class CancelPatientTransactionsController extends Controller {
public function __construct(
protected InpatientFinanceService $inpatientFinanceService
){}
public function cancel_receipt($billing_point, $deposit_id) {
$billing_points_array = [
2 => "investigation_deposits", 3 => "treatment_deposits",
4 => "procedure_deposits", 5 => "sundries_deposits",
8 => "service_deposits", 10 => "service_deposits", 11 => "central_billing_deposits", 16 => "eye_glasses_deposits"
];
$deposit_details = DB::table($billing_points_array[$billing_point])
->find($deposit_id);
return view('patient_finance::cancel_patient_transactions.cancel_receipt', compact('deposit_details', 'billing_point'));
}
public function cancel_invoice($billing_point, $deposit_id) {
$deposit_details = DB::table('patient_category_invoices')
->find($deposit_id);
return view('patient_finance::cancel_patient_transactions.cancel_invoice', compact('deposit_details', 'billing_point'));
}
public function confirm_cancel_receipt(Request $request) {
$receipt_number = "";
$patient_id = 0;
$episode_id = 0;
$originally_billed_by = 0;
$originally_billed_on = 0;
$billing_type = 1;
if (isset($request->is_invoice) && $request->is_invoice ==1) {
$billing_type = 2;
$invoice_deposit = PatientCategoryInvoice::find($request->deposit_id);
$items = explode(",", $invoice_deposit->items_ids);
$quantities = explode(",", $invoice_deposit->items_quantity);
$receipt_number = $invoice_deposit->receipt_number;
$patient_id = $invoice_deposit->patient_id;
$episode_id = $invoice_deposit->episode_id;
$originally_billed_by = $invoice_deposit->created_by;
$originally_billed_on = $invoice_deposit->created_at;
$amount_cancelled = $invoice_deposit->patient_amount;
$order_ids_array = explode(",", $invoice_deposit->order_ids);
if ($request->billing_point == 3) {
for($i = 0; $i < count($order_ids_array); $i++){
Treatment::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
DB::table('treatment_deposits')
->where('receipt_number', $receipt_number)
->delete();
} elseif ($request->billing_point == 2) {
for($i = 0; $i < count($order_ids_array); $i++){
OrderedInvestigation::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
DB::table('investigation_deposits')
->where('receipt_number', $receipt_number)
->delete();
} elseif ($request->billing_point == 4) {
for($i = 0; $i < count($order_ids_array); $i++){
OrderedProcedure::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
DB::table('procedure_deposits')
->where('receipt_number', $receipt_number)
->delete();
} elseif ($request->billing_point == 5) {
for($i = 0; $i < count($order_ids_array); $i++){
OrderedSundry::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
DB::table('sundries_deposits')
->where('receipt_number', $receipt_number)
->delete();
} elseif ($request->billing_point == 8) {
for($i = 0; $i < count($order_ids_array); $i++){
OrderedService::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
DB::table('service_deposits')
->where('receipt_number', $receipt_number)
->delete();
} elseif ($request->billing_point == 10) {
DB::table('service_deposits')
->where('receipt_number', $receipt_number)
->delete();
$inpatient_info = InpatientBill::where(['patient_id' => $patient_id,'episode_id' => $episode_id])->first();
if ($inpatient_info) {
$inpatient_info->amount_to_pay = $inpatient_info->amount_to_pay + $amount_cancelled;
$inpatient_info->save();
}
DB::table('inpatient_ward_discounts')
->where('receipt_number', $receipt_number)
->delete();
} elseif ($request->billing_point == 16) {
for($i = 0; $i < count($order_ids_array); $i++){
OrderedEyeGlasses::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
DB::table('eye_glasses_deposits')
->where('receipt_number', $receipt_number)
->delete();
}
} else {
if ($request->billing_point == 3) {
$treatment_deposit = TreatmentDeposits::find($request->deposit_id);
$items = explode(",", $treatment_deposit->treatment_items);
$amounts = explode(",", $treatment_deposit->treatment_subtotals);
$treatment_quantities = explode(",", $treatment_deposit->treatment_quantities);
$receipt_number = $treatment_deposit->receipt_number;
$patient_id = $treatment_deposit->patient_id;
$episode_id = $treatment_deposit->episode_id;
$originally_billed_by = $treatment_deposit->created_by;
$originally_billed_on = $treatment_deposit->created_at;
$order_ids_array = explode(",", $treatment_deposit->order_ids);
// reverse the chart of accounts
for($i = 0; $i < count($items); $i++){
$this->update_coa_balance($items[$i], $amounts[$i], "drugs");
$this->add_drug_stock($items[$i], $treatment_quantities[$i] ?? 0);
//reverse the batches too
reverse_dispensed_item_batches(1, $items[$i], $treatment_quantities[$i] ?? 0, $patient_id, 'treatments', $treatment_deposit->treatment_id);
}
for($i = 0; $i < count($order_ids_array); $i++){
Treatment::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
DB::table('treatment_deposits')
->where('id', $request->deposit_id)
->delete();
} elseif ($request->billing_point == 2) {
$investigation_deposit = InvestigationDeposit::find($request->deposit_id);
$items = explode(",", $investigation_deposit->investigation_items);
$amounts = explode(",", $investigation_deposit->investigation_amounts);
$receipt_number = $investigation_deposit->receipt_number;
$patient_id = $investigation_deposit->patient_id;
$episode_id = $investigation_deposit->episode_id;
$originally_billed_by = $investigation_deposit->created_by;
$originally_billed_on = $investigation_deposit->created_at;
$order_ids_array = explode(",", $investigation_deposit->order_ids);
// reverse the chart of accounts
for($i = 0; $i < count($items); $i++){
$this->update_coa_balance($items[$i], $amounts[$i], "investigations");
}
for($i = 0; $i < count($order_ids_array); $i++){
OrderedInvestigation::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
DB::table('investigation_deposits')
->where('id', $request->deposit_id)
->delete();
} elseif ($request->billing_point == 4) {
$procedure_deposit = ProcedureDeposit::find($request->deposit_id);
$items = explode(",", $procedure_deposit->procedure_items);
$amounts = explode(",", $procedure_deposit->procedure_amounts);
$receipt_number = $procedure_deposit->receipt_number;
$patient_id = $procedure_deposit->patient_id;
$episode_id = $procedure_deposit->episode_id;
$originally_billed_by = $procedure_deposit->created_by;
$originally_billed_on = $procedure_deposit->created_at;
$order_ids_array = explode(",", $procedure_deposit->order_ids);
for($i = 0; $i < count($order_ids_array); $i++){
OrderedProcedure::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
// reverse the chart of accounts
for($i = 0; $i < count($items); $i++){
$this->update_coa_balance($items[$i], $amounts[$i], "procedures");
}
DB::table('procedure_deposits')
->where('id', $request->deposit_id)
->delete();
} elseif ($request->billing_point == 5) {
$sundry_deposit = SundryDeposit::find($request->deposit_id);
$items = explode(",", $sundry_deposit->sundry_items);
$amounts = explode(",", $sundry_deposit->sundry_subtotals);
$quantities = explode(",", $sundry_deposit->sundry_quantity);
$receipt_number = $sundry_deposit->receipt_number;
$patient_id = $sundry_deposit->patient_id;
$episode_id = $sundry_deposit->episode_id;
$originally_billed_by = $sundry_deposit->created_by;
$originally_billed_on = $sundry_deposit->created_at;
$order_ids_array = explode(",", $sundry_deposit->order_ids);
for($i = 0; $i < count($order_ids_array); $i++){
OrderedSundry::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
// reverse the chart of accounts
for($i = 0; $i < count($items); $i++){
$this->update_coa_balance($items[$i], $amounts[$i], "sundries");
$this->add_sundry_stock($items[$i], $quantities[$i] ?? 0);
//reverse the batches too
reverse_dispensed_item_batches(2, $items[$i], $quantities[$i] ?? 0, $patient_id, 'ordered_sundries', null);
}
DB::table('sundries_deposits')
->where('id', $request->deposit_id)
->delete();
} elseif ($request->billing_point == 8) {
$service_deposit = ServiceDeposit::find($request->deposit_id);
$items = explode(",", $service_deposit->items_ids);
$amounts = explode(",", $service_deposit->items_amounts);
$receipt_number = $service_deposit->receipt_number;
$patient_id = $service_deposit->patient_id;
$episode_id = $service_deposit->episode_id;
$originally_billed_by = $service_deposit->created_by;
$originally_billed_on = $service_deposit->created_at;
$order_ids_array = explode(",", $service_deposit->order_ids);
for($i = 0; $i < count($order_ids_array); $i++){
OrderedService::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
// reverse the chart of accounts
for($i = 0; $i < count($items); $i++){
$this->update_coa_balance($items[$i], $amounts[$i], "services");
}
DB::table('service_deposits')
->where('id', $request->deposit_id)
->delete();
} elseif ($request->billing_point == 10) {
$service_deposit = ServiceDeposit::find($request->deposit_id);
$amount_cancelled = $service_deposit->patient_amount_paid;
$receipt_number = $service_deposit->receipt_number;
$patient_id = $service_deposit->patient_id;
$episode_id = $service_deposit->episode_id;
$originally_billed_by = $service_deposit->created_by;
$originally_billed_on = $service_deposit->created_at;
DB::table('service_deposits')
->where('id', $request->deposit_id)
->delete();
$inpatient_info = InpatientBill::where(['patient_id' => $patient_id,'episode_id' => $episode_id])->first();
if ($inpatient_info) {
$inpatient_info->amount_to_pay = $inpatient_info->amount_to_pay + $amount_cancelled;
$inpatient_info->amount_paid = $inpatient_info->amount_paid - $amount_cancelled;
$inpatient_info->save();
}
DB::table('inpatient_ward_discounts')
->where('receipt_number', $receipt_number)
->delete();
$this->inpatientFinanceService->unsplit_inpatient_deposit($patient_id, $episode_id, $receipt_number, $amount_cancelled);
} elseif ($request->billing_point == 16) {
$optic_deposit = EyeGlassesDeposits::find($request->deposit_id);
$items = explode(",", $optic_deposit->items);
$amounts = explode(",", $optic_deposit->subtotals);
$quantities = explode(",", $optic_deposit->quantity);
$receipt_number = $optic_deposit->receipt_number;
$patient_id = $optic_deposit->patient_id;
$episode_id = $optic_deposit->episode_id;
$originally_billed_by = $optic_deposit->created_by;
$originally_billed_on = $optic_deposit->created_at;
$order_ids_array = explode(",", $optic_deposit->order_ids);
for ($i = 0; $i < count($order_ids_array); $i++) {
OrderedEyeGlasses::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
// reverse the chart of accounts
for ($i = 0; $i < count($items); $i++) {
$this->update_coa_balance($items[$i], $amounts[$i], "eye_glasses");
$this->add_optics_stock($items[$i], $quantities[$i] ?? 0);
}
DB::table('eye_glasses_deposits')
->where('id', $request->deposit_id)
->delete();
}
}
DB::table('cancel_patient_transactions')->insert([
"patient_id" => $patient_id,
"episode_id" => $episode_id,
"billing_point" => $request->billing_point,
"originally_billed_by" => $originally_billed_by,
"originally_billed_on" => $originally_billed_on,
"cancellation_reason" => $request->cancellation_reason,
"receipt_number" => $receipt_number,
"billing_type" => $billing_type,
"created_by" => auth()->id(),
"created_at" => date('Y-m-d H:i:s'),
"updated_at" => date('Y-m-d H:i:s')
]);
// delete donor discounts
DB::table('donor_discount_details')
->where('receipt_number', $receipt_number)
->delete();
// remove any debts associated
DB::table('debtors')
->where('receipt_number', $receipt_number)
->delete();
// remove any debt plan associated
DB::table('debt_plan')
->where('receipt_number', $receipt_number)
->delete();
// delete the discounts
DB::table('discounts')
->where('receipt_number', $receipt_number)
->delete();
// delete the patient category invoice
DB::table('patient_category_invoices')
->where('receipt_number', $receipt_number)
->where('tag_id', $request->billing_point)
->delete();
// delete the patient payment methods
DB::table('payment_methods_transactions')
->where('receipt_number', $receipt_number)
->delete();
// delete any records in the central billing
DB::table('central_billing_deposits')
->where('receipt_number', $receipt_number)
->where('tag_id', $request->billing_point)
->delete();
// delete any records in the central billing
DB::table('patient_one_off_discounts')
->where('receipt_number', $receipt_number)
->delete();
// remove receipt number from staff performed
DB::table('staff_performed_services')
->where('patient_receipt_number', $receipt_number)
->update(['patient_receipt_number' => null]);
if ($request->patient_amount_paid > 0) {
revert_cash_credits_to_daily_collection_account($request->patient_amount_paid, $receipt_number, true);
}
// check if this receipt has any family/patient account consumptions attached and remove the refund amount
reverse_family_consumption_record($receipt_number, 0, true);
reverse_patient_account_consumption_record($receipt_number, 0, true);
reverse_dependant_consumption_record($receipt_number, 0, true);
flash("Patient transaction has been cancelled")->success();
return redirect('/patient_finance/home');
}
public function cancel_central_billing($receipt_number) {
$deposit_details = DB::table('central_billing_deposits')
->where('receipt_number', $receipt_number)
->get();
return view('patient_finance::cancel_patient_transactions.cancel_central_billing', compact('deposit_details'));
}
public function confirm_cancel_central_billing_receipt(Request $request) {
$receipt_number = $request->receipt_number;
$deposit_details = DB::table('central_billing_deposits')
->where('receipt_number', $receipt_number)
->get();
$patient_id = $deposit_details[0]->patient_id;
$episode_id = $deposit_details[0]->episode_id;
$originally_billed_by = $deposit_details[0]->created_by;
$originally_billed_on = $deposit_details[0]->created_at;
foreach ($deposit_details as $deposit_detail) {
$items = explode(",", $deposit_detail->items_ids);
$amounts = explode(",", $deposit_detail->items_amounts);
$order_ids_array = explode(",", $deposit_detail->order_ids);
$items_quantity_array = explode(",", $deposit_detail->items_quantity);
if ($deposit_detail->tag_id == 2) {
// investigations
for($i = 0; $i < count($order_ids_array); $i++){
OrderedInvestigation::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
for($i = 0; $i < count($items); $i++){
$this->update_coa_balance($items[$i], $amounts[$i], "investigations");
}
DB::table('investigation_deposits')
->where('receipt_number', $receipt_number)
->delete();
} else if ($deposit_detail->tag_id == 3) {
// treatments
for($i = 0; $i < count($order_ids_array); $i++){
Treatment::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
DB::table('treatment_deposits')
->where('receipt_number', $receipt_number)
->delete();
// reverse the chart of accounts
for($i = 0; $i < count($items); $i++){
$this->update_coa_balance($items[$i], $amounts[$i], "drugs");
$this->add_drug_stock($items[$i], $items_quantity_array[$i] ?? 0);
//reverse the batches too
$treatment = Treatment::where(['patient_id' => $patient_id, 'episode_id' => $episode_id])->first();
if ($treatment) {
reverse_dispensed_item_batches(1, $items[$i], $items_quantity_array[$i] ?? 0, $patient_id, 'treatments', $treatment->id);
}
}
} else if ($deposit_detail->tag_id == 4) {
// procedures
for($i = 0; $i < count($order_ids_array); $i++){
OrderedProcedure::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
// reverse the chart of accounts
for($i = 0; $i < count($items); $i++){
$this->update_coa_balance($items[$i], $amounts[$i], "procedures");
}
DB::table('procedure_deposits')
->where('receipt_number', $receipt_number)
->delete();
} else if ($deposit_detail->tag_id == 5) {
// sundries
for($i = 0; $i < count($order_ids_array); $i++){
OrderedSundry::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
// reverse the chart of accounts
for($i = 0; $i < count($items); $i++){
$this->update_coa_balance($items[$i], $amounts[$i], "sundries");
$this->add_sundry_stock($items[$i], $items_quantity_array[$i] ?? 0);
//reverse the batches too
reverse_dispensed_item_batches(2, $items[$i], $items_quantity_array[$i] ?? 0, $patient_id, 'ordered_sundries', null);
}
DB::table('sundries_deposits')
->where('receipt_number', $receipt_number)
->delete();
} else if ($deposit_detail->tag_id == 8) {
// services/consultations
for($i = 0; $i < count($order_ids_array); $i++){
OrderedService::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
// check for doctor's consultation
$doc_consultation_id = get_consultation_service_id_allocated_at_episode_consultation($patient_id, $episode_id);
// reverse the chart of accounts
for($i = 0; $i < count($items); $i++){
$this->update_coa_balance($items[$i], $amounts[$i], "services");
}
DB::table('service_deposits')
->where('receipt_number', $receipt_number)
->delete();
} else if ($deposit_detail->tag_id == 16) {
// eye glasses
for($i = 0; $i < count($order_ids_array); $i++){
OrderedEyeGlasses::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
}
// reverse the chart of accounts
for($i = 0; $i < count($items); $i++){
$this->update_coa_balance($items[$i], $amounts[$i], "eye_glasses");
$this->add_optics_stock($items[$i], $items_quantity_array[$i] ?? 0);
}
DB::table('eye_glasses_deposits')
->where('receipt_number', $receipt_number)
->delete();
}
}
DB::table('cancel_patient_transactions')->insert([
"patient_id" => $patient_id,
"episode_id" => $episode_id,
"billing_point" => 11,
"originally_billed_by" => $originally_billed_by,
"originally_billed_on" => $originally_billed_on,
"cancellation_reason" => $request->cancellation_reason,
"receipt_number" => $receipt_number,
"created_by" => auth()->id(),
"created_at" => date('Y-m-d H:i:s'),
"updated_at" => date('Y-m-d H:i:s')
]);
// delete donor discounts
DB::table('donor_discount_details')
->where('receipt_number', $receipt_number)
->delete();
// remove any debts associated
DB::table('debtors')
->where('receipt_number', $receipt_number)
->delete();
// remove any debt plan associated
DB::table('debt_plan')
->where('receipt_number', $receipt_number)
->delete();
// delete the discounts
DB::table('discounts')
->where('receipt_number', $receipt_number)
->delete();
// delete the patient category invoice
DB::table('patient_category_invoices')
->where('receipt_number', $receipt_number)
->delete();
// delete the patient payment methods
DB::table('payment_methods_transactions')
->where('receipt_number', $receipt_number)
->delete();
// delete any records in the central billing
DB::table('central_billing_deposits')
->where('receipt_number', $receipt_number)
->delete();
// remove receipt number from staff performed
DB::table('staff_performed_services')
->where('patient_receipt_number', $receipt_number)
->update(['patient_receipt_number' => null]);
// delete any records in the central billing
DB::table('patient_one_off_discounts')
->where('receipt_number', $receipt_number)
->delete();
if ($request->patient_amount_paid > 0) {
revert_cash_credits_to_daily_collection_account($request->patient_amount_paid, $receipt_number, true);
}
// check if this receipt has any family/patient account consumptions attached and remove the refund amount
reverse_family_consumption_record($receipt_number, 0, true);
reverse_patient_account_consumption_record($receipt_number, 0, true);
flash("Central billing patient transaction has been cancelled")->success();
return redirect('/patient_finance/home');
}
public function update_coa_balance ($item_id, $amount, $table) {
$account_id = get_name($item_id, "id", "account_id", $table);
$account_balance = get_name($account_id, "id", "balance", "chart_of_accounts");
$new_balance = $account_balance - $amount;
ChartOfAccount::where(['id' => $account_id])->update(['balance' => $new_balance]);
}
public function cancelled_patient_transactions_report(Request $request) {
$search_text = "";
if (isset($request->user_id) && $request->user_id != 0) {
$cancellations = DB::table('cancel_patient_transactions')
->where('created_by', $request->user_id)->get();
$search_text = "Showing results for " . get_full_name($request->user_id, 'id', 'first_name', 'last_name', 'users');
} else {
if($request->search_by == 1){
// custom date
$start_date = Carbon::createFromFormat('d/m/Y', $request->reg_date)->startOfDay()->toDateTimeString();
$end_date = Carbon::createFromFormat('d/m/Y', $request->reg_date)->endOfDay()->toDateTimeString();
$search_text = "Showing cancellations made between " . streamline_date_plain($start_date) . " and " . streamline_date_plain($end_date);
} elseif($request->search_by == 2){
// custom date range
$start_date = Carbon::createFromFormat('d/m/Y', $request->start_date)->startOfDay()->toDateTimeString();
$end_date = Carbon::createFromFormat('d/m/Y', $request->end_date)->endOfDay()->toDateTimeString();
$search_text = "Showing cancellations made between " . streamline_date_plain($start_date) . " and " . streamline_date_plain($end_date);
} else {
// last 24 hours
$start_date = Carbon::now()->subDay()->toDateTimeString();
$end_date = Carbon::now()->toDateTimeString();
$search_text = "Showing cancellations in the past 24 hours";
}
$cancellations = DB::table('cancel_patient_transactions')
->whereBetween('created_at', [$start_date, $end_date])->get();
}
$tags = FinancePointTag::pluck('name', 'id');
return view('patient_finance::cancel_patient_transactions.cancelled_patient_transactions_report', compact('search_text', 'cancellations', 'tags'));
}
public function add_drug_stock($drug_id, $amount_returned) {
if (get_inventory_reduction_point() == 2) {
$drug = Drug::withTrashed()->find($drug_id);
$current_stock = $drug->pharmacy_stock;
$new_stock = $current_stock + $amount_returned;
$drug->pharmacy_stock = $new_stock;
$drug->update();
}
}
public function add_sundry_stock($sundry_id, $amount_returned) {
if (get_inventory_reduction_point() == 2) {
$sundry = Sundry::withTrashed()->find($sundry_id);
$current_stock = $sundry->pharmacy_stock;
$new_stock = $current_stock + $amount_returned;
$sundry->pharmacy_stock = $new_stock;
$sundry->update();
}
}
public function add_optics_stock($id, $amount_returned) {
if (get_inventory_reduction_point() == 2) {
$optic = EyeGlasses::withTrashed()->find($id);
$current_stock = $optic->store_stock;
$new_stock = $current_stock - $amount_returned;
$optic->store_stock = $new_stock;
$optic->update();
}
}
public function cancel_chi_deposit($receipt_number) {
$deposit_details = DB::table('chi_deposits')
->where('receipt_number', $receipt_number)
->get();
return view('patient_finance::cancel_patient_transactions.cancel_chi_deposit', compact('deposit_details'));
}
public function confirm_cancel_chi_deposit(Request $request) {
$receipt_number = $request->receipt_number;
$deposit_details = DB::table('chi_deposits')
->where('receipt_number', $receipt_number)
->get();
$patient_id = $deposit_details[0]->patient_id;
$episode_id = $deposit_details[0]->episode_id;
$originally_billed_by = $deposit_details[0]->created_by;
$originally_billed_on = $deposit_details[0]->created_at;
foreach ($deposit_details as $deposit_detail) {
$items = explode(",", $deposit_detail->items_ids);
$order_ids_array = explode(",", $deposit_detail->order_ids);
$items_quantity_array = explode(",", $deposit_detail->items_quantity);
if ($deposit_detail->tag_id == 2) {
// investigations
for($i = 0; $i < count($order_ids_array); $i++){
OrderedInvestigation::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
$this->undo_insurance_claim($order_ids_array[$i], 3);
}
DB::table('investigation_deposits')
->where('receipt_number', $receipt_number)
->delete();
} else if ($deposit_detail->tag_id == 3) {
// treatments
for($i = 0; $i < count($order_ids_array); $i++){
Treatment::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
$this->undo_insurance_claim($order_ids_array[$i], 4);
}
DB::table('treatment_deposits')
->where('receipt_number', $receipt_number)
->delete();
// reverse the chart of accounts
for($i = 0; $i < count($items); $i++){
$this->add_drug_stock($items[$i], $items_quantity_array[$i] ?? 0);
//reverse the batches too
$treatment = Treatment::where(['patient_id' => $patient_id, 'episode_id' => $episode_id])->first();
if ($treatment) {
reverse_dispensed_item_batches(1, $items[$i], $items_quantity_array[$i] ?? 0, $patient_id, 'treatments', $treatment->id);
}
}
} else if ($deposit_detail->tag_id == 4) {
// procedures
for($i = 0; $i < count($order_ids_array); $i++){
OrderedProcedure::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
$this->undo_insurance_claim($order_ids_array[$i], 2);
}
DB::table('procedure_deposits')
->where('receipt_number', $receipt_number)
->delete();
} else if ($deposit_detail->tag_id == 5) {
// sundries
for($i = 0; $i < count($order_ids_array); $i++){
OrderedSundry::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
$this->undo_insurance_claim($order_ids_array[$i], 5);
}
// reverse the chart of accounts
for($i = 0; $i < count($items); $i++){
$this->add_sundry_stock($items[$i], $items_quantity_array[$i] ?? 0);
//reverse the batches too
reverse_dispensed_item_batches(2, $items[$i], $items_quantity_array[$i] ?? 0, $patient_id, 'ordered_sundries', null);
}
DB::table('sundries_deposits')
->where('receipt_number', $receipt_number)
->delete();
} else if ($deposit_detail->tag_id == 8) {
// services/consultations
for($i = 0; $i < count($order_ids_array); $i++){
OrderedService::where(['id' => $order_ids_array[$i]])->update(['payment_status' => 0]);
$this->undo_insurance_claim($order_ids_array[$i], 1);
}
DB::table('service_deposits')
->where('receipt_number', $receipt_number)
->delete();
}
}
DB::table('cancel_patient_transactions')->insert([
"patient_id" => $patient_id,
"episode_id" => $episode_id,
"billing_point" => 18,
"originally_billed_by" => $originally_billed_by,
"originally_billed_on" => $originally_billed_on,
"cancellation_reason" => $request->cancellation_reason,
"receipt_number" => $receipt_number,
"created_by" => auth()->id(),
"created_at" => date('Y-m-d H:i:s'),
"updated_at" => date('Y-m-d H:i:s')
]);
// remove any debts associated
DB::table('debtors')
->where('receipt_number', $receipt_number)
->delete();
// remove any debt plan associated
DB::table('debt_plan')
->where('receipt_number', $receipt_number)
->delete();
// delete the discounts
DB::table('discounts')
->where('receipt_number', $receipt_number)
->delete();
// delete the patient payment methods
DB::table('payment_methods_transactions')
->where('receipt_number', $receipt_number)
->delete();
// delete any records in the central billing
DB::table('chi_deposits')
->where('receipt_number', $receipt_number)
->delete();
// remove receipt number from staff performed
DB::table('staff_performed_services')
->where('patient_receipt_number', $receipt_number)
->update(['patient_receipt_number' => null]);
// delete any records in the central billing
DB::table('patient_one_off_discounts')
->where('receipt_number', $receipt_number)
->delete();
if ($request->patient_amount_paid > 0) {
revert_cash_credits_to_daily_collection_account($request->patient_amount_paid, $receipt_number, true);
}
// check if this receipt has any family/patient account consumptions attached and remove the refund amount
reverse_family_consumption_record($receipt_number, 0, true);
reverse_patient_account_consumption_record($receipt_number, 0, true);
flash("CHI billing patient transaction has been cancelled")->success();
return redirect('/patient_finance/home');
}
public function undo_insurance_claim($order_id, $item_type) {
$claim = InsuranceClaim::where('order_id', $order_id)
->where('item_type', $item_type)
->first();
if ($claim) {
$service_ids = explode(",", $claim->service_ids);
$tariff_amounts = explode(",", $claim->tariff_amounts);
$benefit_ids_array = explode(",", $claim->benefit_ids);
$patient_id = $claim->patient_id;
$insurance_member = DB::table('insurance_members')->where('patient_id', $patient_id)->select('family_id', 'group_id')->first();
for($i = 0; $i < count($service_ids); $i++) {
// check if consumption was registered and reverse
if ($tariff_amounts[$i] > 0) {
remove_insurance_item_consumption($patient_id, $insurance_member->family_id, $benefit_ids_array[$i], $service_ids[$i], $claim->item_type, $tariff_amounts[$i]);
}
}
// finally generate a new claim
generate_insurance_claim($order_id, $claim->item_type);
}
}
}
@@ -0,0 +1,13 @@
<?php
namespace Modules\PatientFinance\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,187 @@
<?php
namespace Modules\PatientFinance\Http\Controllers;
use Carbon\Carbon;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Streamline\Models\FinancePointTag;
use Streamline\Models\PatientPaymentMethod;
use Streamline\Models\PaymentMethodsTransaction;
use Streamline\Models\User;
use Streamline\Services\PatientFinance\PatientPaymentMethodService;
use Streamline\Services\UserService;
class PatientPaymentMethodsController extends Controller {
public function __construct(
protected UserService $userService,
protected PatientPaymentMethodService $paymentMethodService,
)
{
}
public function index() {
$methods = PatientPaymentMethod::get();
$users = $this->userService->pluckUserFullName();
return view('patient_finance::patient_payment_methods.index', compact('methods', 'users'));
}
public function create() {
return view('patient_finance::patient_payment_methods.create');
}
public function store(Request $request) {
request()->validate([
'name' => 'required'
]);
$method = new PatientPaymentMethod;
$logged_in_user_id = Auth::user()->id;
$method->name = $request->name;
$method->is_ref_required = $request->is_ref_required;
$method->created_by = $logged_in_user_id;
$method->updated_by = $logged_in_user_id;
try {
if ($method->name != "" || !is_null($method->name)) {
$method->save();
}
flash("Payment method has been saved")->success();
return redirect("/patient_payment_methods");
} catch (QueryException $e) {
flash("An error occurred")->error();
return back()->withInput();
}
}
public function edit($id) {
$method = PatientPaymentMethod::where(['id' => $id])->first();
if (!$method) {
flash()->error("Payment method not found");
return redirect('/patient_payment_methods');
} else {
return view('patient_finance::patient_payment_methods.edit', compact('method'));
}
}
public function update(Request $request, $id) {
request()->validate([
'name' => 'required'
]);
//validation passed
$method = PatientPaymentMethod::find($id);
$method->name = $request->name;
$method->is_ref_required = $request->is_ref_required;
try {
$method->save();
flash("Payment method has been updated")->success();
return redirect("/patient_payment_methods");
} catch (QueryException $e) {
flash("An error occurred")->error();
return back()->withInput();
}
}
public function delete($id) {
$method = PatientPaymentMethod::find($id);
if ($method->delete()) {
flash("Payment method has been deleted.")->success();
return redirect('/patient_payment_methods');
}
}
public function inactive() {
$methods = PatientPaymentMethod::onlyTrashed()
->orderBy('name', 'asc')
->paginate(50);
if (count($methods) < 1) {
flash()->error("There is no inactive payment method");
return redirect('/patient_payment_methods');
} else {
return view('patient_finance::patient_payment_methods.inactive', compact('methods'));
}
}
public function activate($id) {
$method = PatientPaymentMethod::withTrashed()->find($id);
if($method->restore()){
flash("Payment method has been activated.")->success();
return redirect('/patient_payment_methods/inactive');
}
}
public function reports(Request $request) {
$search_text = "";
$filters = [];
$payment_methods = PatientPaymentMethod::pluck('name', 'id');
$tags = FinancePointTag::pluck('name', 'id');
if (isset($request->payment_method) && $request->payment_method != -1) {
array_push($filters, ['payment_method_id', '=', $request->payment_method]);
$search_text .= "Payment Method: " . (($request->payment_method == 0) ? "Cash" : $payment_methods[$request->payment_method]) . " | ";
}
if (isset($request->date_period)) {
switch ($request->date_period) {
default:
case "today":
$search_text .= "Today" . " | ";
$start = Carbon::today()->startOfDay();
$end = Carbon::today()->endOfDay();
break;
case "yesterday":
$search_text .= "Yesterday" . " | ";
$start = Carbon::yesterday()->startOfDay();
$end = Carbon::yesterday()->endOfDay();
break;
case "custom_date":
$search_text .= "On: " . streamline_date($request->start_date) . " | ";
$start = Carbon::createFromFormat('d-m-Y', $request->start_date)->startOfDay();
$end = Carbon::createFromFormat('d-m-Y', $request->start_date)->endOfDay();
break;
case "custom_date_range":
$search_text .= "From: " . streamline_date($request->start_date) . " to " . streamline_date($request->end_date) . " | ";
$start = Carbon::createFromFormat('d-m-Y', $request->start_date)->startOfDay();
$end = Carbon::createFromFormat('d-m-Y', $request->end_date)->endOfDay();
break;
}
} else {
$search_text .= "Today" . " | ";
$start = Carbon::today()->startOfDay();
$end = Carbon::today()->endOfDay();
}
if (isset($request->staff_member) && $request->staff_member != 0) {
$records = PaymentMethodsTransaction::where('created_by', $request->staff_member)
->where($filters)
->whereBetween('created_at', [$start, $end])
->get();
$search_text .= "Staff Member: " . get_full_name($request->staff_member, 'id', 'first_name', 'last_name', 'users');
} else {
$search_text .= "Staff Member: All";
$records = PaymentMethodsTransaction::where($filters)->whereBetween('created_at', [$start, $end])->get();
}
$users = $this->userService->pluckUserFullName();
return view('patient_finance::patient_payment_methods.reports', compact('users', 'search_text', 'records', 'payment_methods', 'tags'));
}
public function isRefRequired(Request $request): int
{
return $this->paymentMethodService->isRefRequired($request->id);
}
}
@@ -0,0 +1,287 @@
<?php
namespace Modules\PatientFinance\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Streamline\Models\HospitalInformation;
use Streamline\Models\InvestigationDeposit;
use Streamline\Models\Patient;
use Streamline\Models\PatientRefunds;
use Streamline\Models\PaymentMethodsTransaction;
use Streamline\Models\ProcedureDeposit;
use Streamline\Models\ServiceDeposit;
use Streamline\Models\SundryDeposit;
use Streamline\Models\TrackReceipt;
use Streamline\Models\TreatmentDeposits;
use Streamline\Services\WardManagement\InpatientFinanceService;
class PatientRefundController extends Controller {
public function __construct(
protected InpatientFinanceService $inpatientFinanceService
){}
public function choose_refund_point()
{
$episode_id = session()->get('episode_id');
// exclude central billing so that they have to go and cancel it instead
$exclude_receipts = DB::table('central_billing_deposits')->where('episode_id', $episode_id)->distinct()->pluck('receipt_number')->toArray();
// check if consultation or other services is available for refund
$service_items = ServiceDeposit::where(['episode_id' => $episode_id])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->get(['service_type']);
$service_deposits_types = [];
foreach ($service_items as $item) {
$service_deposits_types[] = $item->service_type;
}
if (in_array('Consultation', $service_deposits_types)) {
$consultations = 1;
} else {
$consultations = 0;
}
if (in_array('Co_Payment', $service_deposits_types)) {
$co_payment = 1;
} else {
$co_payment = 0;
}
if (in_array('Inpatient_Deposit', $service_deposits_types)) {
$inpatient_deposits = 1;
} else {
$inpatient_deposits = 0;
}
if (in_array('Service', $service_deposits_types) || in_array('Other_service', $service_deposits_types) || in_array('Services', $service_deposits_types)) {
$other_services = 1;
} else {
$other_services = 0;
}
// check if treatments is available for refund
$prescription = TreatmentDeposits::where(['episode_id' => $episode_id])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->count() > 0 ? 1 : 0;
// check if investigations is available for refund
$investigations = InvestigationDeposit::where(['episode_id' => $episode_id])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->count() ? 1 : 0;
// check if procedures is available for refund
$procedures_paid = ProcedureDeposit::where(['episode_id' => $episode_id])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->count() ? 1 : 0;
// check if sundries is available for refund
$sundries_paid = SundryDeposit::where(['episode_id' => $episode_id])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->count() ? 1 : 0;
return view("patient_finance::patient_refund.choose_refund_point", compact("consultations", "other_services", "prescription", "investigations", "procedures_paid", "inpatient_deposits", "sundries_paid", "co_payment"));
}
public function register_refund_details(Request $request) {
$episode_id = session()->get('episode_id');
$refund_point = $request->refund_point;
// exclude central billing so that they have to go and cancel it instead
$exclude_receipts = DB::table('central_billing_deposits')->where('episode_id', $episode_id)->distinct()->pluck('receipt_number')->toArray();
switch ($refund_point) {
case 1:
// Consultation
$services = ServiceDeposit::where(['episode_id' => $episode_id, 'service_type' => 'Consultation'])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->orderBy('created_at', 'desc')->get();
$compact = compact('services', 'refund_point');
break;
case 2:
// Treatment
$paid_treatments = TreatmentDeposits::where(['episode_id' => $episode_id])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->get();
$compact = compact('paid_treatments', 'refund_point');
break;
case 3:
// Investigations
$investigations = InvestigationDeposit::where(['episode_id' => $episode_id])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->orderBy('created_at', 'desc')->get();
$compact = compact('investigations', 'refund_point');
break;
case 4:
// Procedures
$procedures = ProcedureDeposit::where(['episode_id' => $episode_id])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->orderBy('created_at', 'desc')->get();
$compact = compact('procedures', 'refund_point');
break;
case 5:
// Other Services
$services = ServiceDeposit::where(['episode_id' => $episode_id, 'service_type' => 'Services'])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->orderBy('created_at', 'desc')->get();
$compact = compact('services', 'refund_point');
break;
case 6:
// Inpatient Deposits
$inpatient_fees = ServiceDeposit::where(['episode_id' => $episode_id, 'service_type' => 'Inpatient_Deposit'])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->orderBy('created_at', 'desc')->get();
$compact = compact('inpatient_fees', 'refund_point');
break;
case 7:
// Sundries
$paid_sundries = SundryDeposit::where(['episode_id' => $episode_id])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->get();
$compact = compact('paid_sundries', 'refund_point');
break;
case 8:
// Co-Payment
$services = ServiceDeposit::where(['episode_id' => $episode_id, 'service_type' => 'Co_Payment'])->whereNotIn('receipt_number', $exclude_receipts)->whereNull('received')->orderBy('created_at', 'desc')->get();
$compact = compact('services', 'refund_point');
break;
default:
$compact = compact('episode_id');
break;
}
return view("patient_finance::patient_refund.register_refund_details", $compact);
}
public function save_refund_details(Request $request)
{
$patient_id = session()->get('patient_id');
$episode_id = session()->get('episode_id');
$refund_point = $request->refund_point;
$deposit_id = $request->id;
$maximum_refund_amount = $request->maximum_refund_amount;
$refund_amount = $request->refund_amount;
$new_patient_amount_paid = $maximum_refund_amount - $refund_amount;
$refund_reason = $request->refund_reason;
$original_receipt_number = "";
$refund_date = Carbon::parse($request->refund_date)->format('Y-m-d');
// update the track_receipt table to include created receipt
$track_receipts = new TrackReceipt;
$track_receipts->created_by = Auth::id();
$track_receipts->reason = 'Patient Refunds';
$track_receipts->save();
$receipt_number = sprintf("%04u", $track_receipts->id);
if ($refund_point == 1) {
// Consultation
$consultation = ServiceDeposit::find($deposit_id);
$original_receipt_number = $consultation->receipt_number;
$consultation->patient_amount_paid = $new_patient_amount_paid;
$consultation->refund_amount = $consultation->refund_amount + $refund_amount;
$consultation->update();
if ($request->reverse_doctor_fees == 1) {
reverse_staff_fee_payment($patient_id, $episode_id, 3);
}
split_service_payment($deposit_id);
} elseif ($refund_point == 2) {
// Treatment
$treatment = TreatmentDeposits::find($deposit_id);
$original_receipt_number = $treatment->receipt_number;
$treatment->patient_amount_paid = $new_patient_amount_paid;
$treatment->refund_amount = $treatment->refund_amount + $refund_amount;
$treatment->update();
split_treatment_payment($deposit_id);
} elseif ($refund_point == 3) {
// Investigation
$investigation = InvestigationDeposit::find($deposit_id);
$original_receipt_number = $investigation->receipt_number;
$investigation->patient_amount_paid = $new_patient_amount_paid;
$investigation->refund_amount = $investigation->refund_amount + $refund_amount;
$investigation->update();
if ($request->reverse_doctor_fees == 1) {
reverse_staff_fee_payment($patient_id, $episode_id, 2);
}
split_investigation_payment($deposit_id);
} elseif ($refund_point == 4) {
// Procedures
$procedures = ProcedureDeposit::find($deposit_id);
$original_receipt_number = $procedures->receipt_number;
$procedures->patient_amount_paid = $new_patient_amount_paid;
$procedures->refund_amount = $procedures->refund_amount + $refund_amount;
$procedures->update();
if ($request->reverse_doctor_fees == 1) {
reverse_staff_fee_payment($patient_id, $episode_id, 1);
}
split_procedure_payment($deposit_id);
} elseif ($refund_point == 5 || $refund_point == 6 || $refund_point == 8) {
// Other Services - Inpatient Deposits - CoPayment
$other_services = ServiceDeposit::find($deposit_id);
$original_receipt_number = $other_services->receipt_number;
$other_services->patient_amount_paid = $new_patient_amount_paid;
$other_services->refund_amount = $other_services->refund_amount + $refund_amount;
$other_services->update();
if ($refund_point == 6) {
$this->inpatientFinanceService->unsplit_inpatient_deposit($patient_id, $episode_id, $other_services->receipt_number, $refund_amount);
} else {
split_service_payment($deposit_id);
}
} elseif ($refund_point == 7) {
// Sundries
$sundries = SundryDeposit::find($deposit_id);
$original_receipt_number = $sundries->receipt_number;
$sundries->patient_amount_paid = $new_patient_amount_paid;
$sundries->refund_amount = $sundries->refund_amount + $refund_amount;
$sundries->update();
split_sundry_payment($deposit_id);
}
revert_cash_credits_to_daily_collection_account($refund_amount, $original_receipt_number, false);
// check if this receipt has any family/patient account consumptions attached and remove the refund amount
reverse_family_consumption_record($original_receipt_number, $refund_amount, false);
reverse_patient_account_consumption_record($original_receipt_number, $refund_amount, false);
reverse_dependant_consumption_record($original_receipt_number, $refund_amount, false);
// reduce the patient paid amount in the payment methods
$payment_methods = DB::table('payment_methods_transactions')
->where('receipt_number', $original_receipt_number)->get();
if (count($payment_methods) > 0) {
$pm_new_patient_amount_paid = $refund_amount;
foreach ($payment_methods as $payment_method) {
$payment_methods_update = PaymentMethodsTransaction::find($payment_method->id);
if ($pm_new_patient_amount_paid > $payment_method->amount) {
$pm_new_patient_amount_paid = $pm_new_patient_amount_paid - $payment_method->amount;
$payment_methods_update->amount = 0;
} else {
$payment_methods_update->amount = $payment_method->amount - $pm_new_patient_amount_paid;
$pm_new_patient_amount_paid = 0;
}
$payment_methods_update->update();
if ($pm_new_patient_amount_paid == 0) {
break;
}
}
}
// create patient refund record
$refund = new PatientRefunds();
$refund->original_patient_amount_paid = $maximum_refund_amount;
$refund->patient_id = $patient_id;
$refund->episode_id = $episode_id;
$refund->refund_amount = $refund_amount;
$refund->refund_reason = $refund_reason;
$refund->refund_date = $refund_date;
$refund->refund_point = $refund_point;
$refund->deposit_id = $deposit_id;
$refund->receipt_number = $receipt_number;
$refund->created_by = Auth::id();
if ($refund->save()) {
// details to be used for receipt
$hospital_information = HospitalInformation::first();
$patient = Patient::find($patient_id);
$receipt_date = date('Y-m-d h:i:s');
return view("patient_finance::patient_refund.receipt", compact('hospital_information', 'receipt_number', 'patient', 'receipt_date', 'refund_amount', 'refund_reason', 'original_receipt_number'));
} else {
flash("Unable to process refund. Please try again later")->error();
return back()->withInput();
}
}
}