Files
streamline-emr/docker/streamline-src/Modules/ClinicalData/Http/Controllers/ServicesController.php
T

464 lines
19 KiB
PHP
Executable File

<?php
namespace Modules\ClinicalData\Http\Controllers;
use Illuminate\Http\Request;
use Streamline\Http\Controllers\StreamlineSetupManager;
use Streamline\Models\ChartOfAccount;
use Streamline\Models\InsuranceClaim;
use Streamline\Models\PriceListCategories;
use Streamline\Models\Services;
use Illuminate\Support\Facades\DB;
use Streamline\Models\Supplier;
use Streamline\Models\User;
use Streamline\Models\Patient;
use Streamline\Models\OrderedService;
use Illuminate\Database\QueryException;
use Streamline\Services\StreamlineSetupServiceInterface;
class ServicesController extends Controller {
public function __construct(protected StreamlineSetupServiceInterface $setupService
) {
$this->middleware('auth');
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index() {
$service_items = Services::where('available', 1)->orderby('name', 'asc')->get();
$chart_of_accounts = ChartOfAccount::where(['type' => 1])->orderBy('name', 'asc')->pluck('name', 'id')->toArray();
$ordered_services_array = [];
$ordered_services = OrderedService::distinct('service_id')->get(['service_id']);
foreach ($ordered_services as $ordered_service) {
$ordered_services_array = array_merge($ordered_services_array, explode(',', $ordered_service->service_id));
}
$ordered_service_ids = array_unique($ordered_services_array);
return view('clinical_data::service_items.index',compact('service_items', 'chart_of_accounts','ordered_service_ids'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create(){
$suppliers = Supplier::orderBy('name','asc')->pluck('name','id')->toArray();
$suppliers = ['' => '- select -'] + $suppliers;
$chart_of_accounts = ChartOfAccount::where(['type' => 1])->orderBy('name', 'asc')->pluck('name', 'id')->toArray();
$chart_of_accounts = ['' => '- select -'] + $chart_of_accounts;
$services = StreamlineSetupManager::get_services_array();
$users = DB::table('users')->orderBy("first_name","asc")->select("id")->get()->toArray();
$users_array = [];
foreach ($users as $value){
$user = User::find($value->id);
if (!is_null($user)) {
$users_array[$value->id] = get_full_name($value->id, 'id', 'first_name', 'last_name', 'users');
}
}
$users_array = ['' => '- Select Staff -'] + $users_array;
return view('clinical_data::service_items.create',compact('suppliers','chart_of_accounts','services','users_array'));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request) {
//if it for streamline setup then you can skip the request validation
if (session()->has('streamline_setup')){
//skip validation
} else {
request()->validate([
'name' => 'required',
]);
}
if (isset($request->skip)) {
//Artisan::call('db:seed', ['--class' => 'ServicesTableSeeder']);
//update the streamline setup table with the new finished step
$this->setupService->saveStep("services registration", 1);
// $streamline_setup = new \Streamline\Models\StreamlineSetupStep;
// $streamline_setup->step = "services registration";
// $streamline_setup->completion_status = 1;
// $streamline_setup->save();
return redirect("investigations/create");
} else {
// get all current price lists
$price_list = PriceListCategories::withTrashed()->select('id')->get();
$price_list_category = [];
$price_list_price = [];
foreach ($price_list as $record){
array_push($price_list_category, $record->id);
array_push($price_list_price, $request->non_insured_price);
}
$service_item = new Services;
$service_item->name = $request->name;
if ($request->attach_to_staff_name == 1) {
$attached_user_id = $request->user_id;
$attached_user_name = get_full_name($attached_user_id, "id", "first_name", "last_name", "users");
$service_item->name = $service_item->name." - ".$attached_user_name;
}
$service_item->insured_price = 0;
$service_item->available = $request->available;
$service_item->non_insured_price = $request->non_insured_price;
$service_item->cost_price = $request->non_insured_price;
$service_item->account_id = $request->account_id;
if (isset($request->price_list_category_id) && isset($request->price_list_price)) {
$service_item->price_list_category = !is_null($request->price_list_category_id) ? implode(",", $request->price_list_category_id) : null;
$service_item->price_list_price = !is_null($request->price_list_price) ? implode(",", $request->price_list_price) : null;
} else {
$service_item->price_list_category = implode(",", $price_list_category);
$service_item->price_list_price = implode(",", $price_list_price);
}
$service_item->insurance_coverage = 0;
$service_item->item_type = $request->type_of_service;
$service_item->supplier_id = 0; // not necessary
$service_item->description = $request->description;
try{
if ($service_item->name != "" && !is_null($service_item->name)) {
$service_item->save();
}
flash("New service item has been added")->success();
if (session()->has('streamline_setup')) {
if (isset($request->selected_services)) {
$selected_services_array = $request->selected_services;
if (!empty($selected_services_array)) {
for ($i=0; $i < count($selected_services_array) ; $i++) {
/* try this magic to get details for the selected service */
$services_array = StreamlineSetupManager::get_services_array();
$key=array_search($selected_services_array[$i], array_column($services_array, 'Item_Name'));
$service_details = $services_array[$key];
/* end of magic trial */
$service_item = new Services;
$service_item->name = $service_details['Item_Name'];
$service_item->cost_price = $service_details['Cost_Price'];
$service_item->insured_price = 0;
$service_item->non_insured_price = $service_details['Non_Insured_Amount'];
$service_item->account_id = $service_details['Account_Id'];
$service_item->item_type = $service_details['Item_Type'];
$service_item->description = $service_details['Description'];
$service_item->save();
}
}
}
$this->setupService->saveStep("services registration", 1);
// $streamline_setup = new \Streamline\Models\StreamlineSetupStep;
// $streamline_setup->step = "services registration";
// $streamline_setup->completion_status = 1;
// $streamline_setup->save();
return redirect("investigations/create");
}
return redirect('/service_items');
} catch (QueryException $e) {
flash("An error occurred")->error();
return back()->withInput();
}
}
flash("Error occurred")->error();
return back()->withInput();
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id){
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id) {
$service = Services::where(['id' => $id])->first();
$chart_of_accounts = ChartOfAccount::where(['type' => 1])->orderBy('name', 'asc')->pluck('name', 'id')->toArray();
$chart_of_accounts = ['' => '- select -'] + $chart_of_accounts;
if (!$service) {
flash()->error("Service not found");
return redirect('/service_items/');
} else {
return view('clinical_data::service_items.edit', compact('service', 'chart_of_accounts'));
}
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id){
$service_item = Services::find($id);
$service_item->name = $request->name;
$service_item->available = $request->available;
$service_item->insured_price = 0;
$service_item->non_insured_price = $request->non_insured_price;
$service_item->price_list_category = !is_null($request->price_list_category_id) ? implode(",", $request->price_list_category_id) : null;
$service_item->price_list_price = !is_null($request->price_list_price) ? implode(",", $request->price_list_price) : null;
$service_item->account_id = $request->account_id;
$service_item->insurance_coverage = 0;
$service_item->item_type = $request->type_of_service;
$service_item->description = $request->description;
if ($service_item->save()) {
flash("Service item has been edited")->success();
return redirect('/service_items');
}
flash("Error occurred")->error();
return back()->withInput();
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id) {
$service = Services::find($id);
if ($service->delete()) {
flash("Service item has been deleted")->success();
return redirect('/service_items');
}
flash("Service has not been deleted")->success();
return redirect('service_items');
}
/**
* Display a listing of the inactive resource(s).
*
* @return \Illuminate\Http\Response
*/
public function inactive() {
$services = Services::onlyTrashed()
->orderBy('name', 'asc')
->get();
return view('clinical_data::service_items.inactive', compact('services'));
}
/**
* Activate the specified resource in storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function activate($id) {
$service = Services::withTrashed()->find($id);
if($service->restore()){
flash("Service has been activated.")->success();
return redirect('/service_items/inactive');
}
}
/*
* order sundries for the patient
*/
public function order_services() {
$patient_id = session()->get('patient_id');
$episode_id = session()->get('episode_id');
$patient = Patient::where('id', $patient_id)->first();
$categories = DB::table('patient_categories')->where('available', 1)->pluck("name", "id");
$services = Services::where('available', 1)->orderBy('name')->pluck('name', 'id');
$ordered_services = DB::table('ordered_services')->whereNull('deleted_at')->where(['patient_id'=>$patient_id, 'episode_id'=>$episode_id, 'payment_status' => 0])->first();
$users_collection = DB::table('users')->orderBy("first_name","asc")->select("id")->get()->toArray();
$users_array = [];
foreach ($users_collection as $value){
$user = \Streamline\Models\User::find($value->id);
if (!is_null($user)) {
$users_array[$value->id] = get_full_name($value->id, 'id', 'first_name', 'last_name', 'users');
}
}
$users_array = ['' => '- select -'] + $users_array;
$employees = DB::table('users')->whereNull('deleted_at')->orderBy('first_name', 'asc')->get();
return view('clinical_data::service_items.ordered_services',compact('patient_id','episode_id','patient','categories','employees','services','ordered_services', 'users_array'));
}
/*
* store ordered sundries for a patient episode
*/
public function store_ordered_services(Request $request) {
if(is_null($request->service_id) || is_null($request->service_id[0])) {
flash("No service has been selected")->error();
return back()->withInput();
} else {
$patient_id = session()->get('patient_id');
$episode_id = session()->get('episode_id');
$service_ids_array = $request->service_id;
$quantity_array = $request->item_quantity;
$service_performed = [];
$service_performed_id = [];
$performed_service_array = $request->performed_services;
$performed_by_array = $request->service_performed_by;
$service_performed_by_amount = $request->service_performed_by_amount;
$service_performed_date = $request->service_performed_date;
// filter to check if all entries have been filled for performed by and discard otherwise
for ($i = 0; $i < count($service_ids_array); $i++) {
// check if it is in the excluded item count
if (isset($performed_service_array[$i]) && $performed_service_array[$i] == 1 && isset($performed_by_array[$i]) && $performed_by_array[$i] != "" &&
isset($service_performed_by_amount[$i]) && $service_performed_by_amount[$i] != "" &&
isset($service_performed_date[$i]) && $service_performed_date[$i] != "") {
$service_performed_id[] = record_staff_that_has_performed_the_service_with_price($patient_id, $episode_id, 3, $service_ids_array[$i], 0,
$performed_by_array[$i], $service_performed_by_amount[$i], $service_performed_date[$i]);
$service_performed[] = 1;
} else {
$service_performed[] = 0;
$service_performed_id[] = 0;
}
}
if (isset($request->order_id) && get_name($request->order_id, 'id', 'payment_status', 'ordered_services') == 0) {
$service_order = Orderedservice::find($request->order_id);
// delete the previous preformed_by_ids
try {
DB::table('staff_performed_services')->whereIn('id', explode(",", $service_order->performed_id))->delete();
} catch (\Exception $e) {}
} else {
$service_order = new Orderedservice;
$service_order->patient_id = $patient_id;
$service_order->episode_id = $episode_id;
$service_order->payment_status = 0; //0 by default to mean not paid
$service_order->created_by = auth()->user()->id;
}
$service_order->service_id = implode(",", $service_ids_array);
$service_order->quantity = implode(",", $quantity_array);
$service_order->performed = implode(",", $service_performed);
$service_order->performed_id = implode(",", $service_performed_id);
$service_order->updated_by = auth()->user()->id;
$service_order->save();
// create an insurance claim for the ordered items
if ($request->patient_insurance_status == 1) {
generate_insurance_claim($service_order->id, 1);
}
flash("Services have been saved")->success();
// redirect to consultation or patient_episode page depending on where the user is from
if (session()->has('redirect_to_consultation')) {
$url = session()->get('redirect_to_consultation');
session()->forget('redirect_to_consultation');
return redirect($url);
} else {
return redirect("/patient_episodes");
}
}
}
public function fetch_service_performance_fee(Request $request) {
$patient_id = $request->patient_id;
$patient_category_id = get_name($patient_id, 'id', 'category_id', 'patients');
$performed_by = $request->performed_by;
$item_id = $request->item_id;
$price_list_category_details = \Streamline\Models\PriceListCategories::where(['patient_category_id' => $patient_category_id])->first();
if ($price_list_category_details) {
$price_list_category_id = $price_list_category_details->id;
$fees_array = get_item_price_and_performance_fee_based_on_price_list_category($performed_by, $item_id, 3, $price_list_category_id);
return ($fees_array[1] == 0) ? $fees_array[0] : $fees_array[1];
} else {
//do this for cases where the there are no price lists for the patient's patient_category
$fees_array = get_item_price_and_performance_fee_array_without_price_list($item_id, $performed_by, 3);
return ($fees_array[1] == 0) ? $fees_array[0] : $fees_array[1];
}
}
public function cancel_ordered_services($order_id) {
$ordered_service = OrderedService::find($order_id);
try {
$ordered_service->delete();
// check if there are any insurance claims available
$claim = InsuranceClaim::where('order_id', $order_id)->where('item_type', 1)->first();
if ($claim) {
$claim->delete();
}
return 1;
} catch (\Exception $exception) {
return 0;
}
}
public function get_service_details(Request $request) {
$patient_id = $request->patient_id;
$patient_insurance_status = $request->patient_insurance_status ?? 0;
$service = DB::table('services')->find($request->service_id);
if(is_numeric($patient_insurance_status) && $patient_insurance_status == 1 && $patient_id != 0 && is_numeric($patient_id)) {
$selling_price = get_item_insurance_co_payment($patient_id, $service->id, 1, false, 0);
} else {
// check if the patient category is attached to a price list
$price_list_id = is_patient_category_attached_to_price_list($patient_id);
if ($price_list_id) {
$selling_price = get_price_list_category_price($price_list_id, 6, $service->id);
} else {
$selling_price = $service->non_insured_price;
}
}
if (is_chi_enabled() && is_patient_item_covered($patient_id, $service->id, 1)) {
$covered_by_chi = '&nbsp;&nbsp;<br><span style="color: darkgreen"><b>Covered by CHI</b></span>';
} else {
$covered_by_chi = "";
}
return json_encode([
"selling_price" => $selling_price,
"covered_by_chi" => $covered_by_chi,
]);
}
}