purityselect/app/Http/Controllers/Admin/Api/PatientController.php
2024-10-25 01:05:27 +05:00

551 lines
22 KiB
PHP

<?php
namespace App\Http\Controllers\Admin\Api;
use App\Classes\Constant;
use App\Events\PatientRegistered;
use App\Http\Controllers\Controller;
use App\Models\Appointment;
use App\Models\Cart;
use App\Models\Item;
use App\Models\ItemHistory;
use App\Models\LabkitOrderItem;
use App\Models\Patient;
use App\Models\PatientNote;
use App\Models\PatientPrescription;
use App\Models\PatientRegActivity;
use App\Models\Setting;
use Carbon\Carbon;
use DateTime;
use Illuminate\Contracts\Routing\UrlGenerator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Illuminate\Auth\Access\AuthorizationException;
use Agence104\LiveKit\VideoGrant;
use App\Events\AppointmentBooked;
use App\Events\PaymentProcessed;
use App\Models\Admin;
use App\Models\Lab;
use App\Models\LabKit;
use App\Models\LicenseNumberModel;
use App\Models\MedicalHistoryAnswer;
use App\Models\PatientPlan;
use App\Models\Plan;
use App\Models\PlanV1;
use App\Models\Prescription;
use App\Models\ProfileAnswer;
use App\Models\ProfileCategory;
use App\Models\QuestionBuilder;
use App\Models\Subscription;
use App\Models\Telemedpro;
use Carbon\CarbonTimeZone;
use DateTimeZone;
use Error;
use Exception;
use Illuminate\Support\Facades\Log;
use Yajra\DataTables\DataTables;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;
use Agence104\LiveKit\AccessToken;
use Agence104\LiveKit\AccessTokenOptions;
use Agence104\LiveKit\RoomCreateOptions;
use Agence104\LiveKit\RoomServiceClient;
class PatientController extends Controller
{
protected $url;
protected $user;
public function __construct(UrlGenerator $url)
{
$this->url = $url;
$this->user = Auth::guard('admin')->user();
}
public function newPatient(Request $request)
{
try {
$this->authorizeForUser($this->user, 'add', new Patient);
$validatedData = $request->validate([
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:patients',
'password' => 'required',
'dob' => 'required|date_format:Y-m-d',
'phone_no' => 'required'
]);
$patient = Patient::create([
'first_name' => $request->input('first_name'),
'last_name' => $request->input('last_name'),
'phone_no' => $request->input('phone_no'),
'email' => $request->input('email'),
'password' => Hash::make($request->input('password')),
'dob' => $request->input('dob'),
'gender' => $request->input('gender') ?? "",
]);
$patient->address = $request->input('address');
$patient->state = $request->input('state');
$patient->city = $request->input('city');
$patient->country = $request->input('country');
$patient->zip_code = $request->input('zip');
$patient->shipping_address = $request->input('address');
$patient->shipping_state = $request->input('state');
$patient->shipping_city = $request->input('city');
$patient->shipping_zipcode = $request->input('zip');
$image = $request->get('profile_pic');
$fileName = 'profile-' . time();
$logo = base64_decode($image);
$ext = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[1]);
$imageName = $fileName . '.' . $ext;
Storage::disk('local')->put("public/profile_pictures/" . $imageName, $logo);
$patient->profile_picture = $imageName;
$patient->save();
if ($patient->dob) {
$birthDate = new DateTime($patient->dob);
$today = new DateTime(date('Y-m-d'));
$age = $today->diff($birthDate)->y;
$patient->age = $age;
} else {
$patient->age = 0;
}
PatientRegActivity::create([
'patient_id' => $patient->id,
'activity' => 'patient_registered'
]);
$setting = Setting::find(1);
event(new PatientRegistered($patient, $validatedData));
return response()
->json([
'data' => $patient
]);
} catch (AuthorizationException $e) {
return $e->getMessage();
}
}
public function patientShippingAddress($id, Request $request)
{
try {
$this->authorizeForUser($this->user, 'edit', new Patient);
$patient = Patient::find($id);
$patient->shipping_address = $request->input('address');
$patient->shipping_state = $request->input('state');
$patient->shipping_city = $request->input('city');
$patient->shipping_zipcode = $request->input('zip');
$patient->save();
return response()
->json([
'data' => $patient
]);
} catch (AuthorizationException $e) {
return $e->getMessage();
}
}
public function patientList(Request $request)
{
try {
$this->authorizeForUser($this->user, 'list', new Patient);
$patients = Patient::query();
// Filter by state
if ($request->input('state') != "all") {
$patients->where('patients.state', $request->input('state'));
}
// Filter by gender
if ($request->input('gender') != "all") {
$patients->where('patients.gender', $request->input('gender'));
}
// Filter by plan (assuming you have a plan field or relation)
if ($request->input('plan') != "all") {
$planNames = $request->input('plan');
$patients->leftJoin('patient_plan', 'patients.id', '=', 'patient_plan.patient_id')
->leftJoin('plans_v1', 'patient_plan.plan_id', '=', 'plans_v1.id')
->where('plans_v1.slug', $planNames);
}
// Join with the carts table to get order details
$patients->leftJoin('carts', 'patients.id', '=', 'carts.patient_id')
->select('patients.*')
->addSelect([
'last_order_date' => Cart::selectRaw('MAX(created_at)')
->whereColumn('patient_id', 'patients.id'),
'total_orders' => Cart::selectRaw('COUNT(*)')
->whereColumn('patient_id', 'patients.id'),
'total_subscriptions' => Cart::selectRaw('COUNT(DISTINCT start_subscription)')
->whereColumn('patient_id', 'patients.id'),
]);
Log::info('PatientList Datatable:', [
'sql' => $patients->toSql(),
'bindings' => $patients->getBindings()
]);
// Use DataTables to process the query
return DataTables::of($patients)->make(true);
} catch (\Exception | Error $e) {
// Log the error
Log::error('Error in patientList: ' . $e->getMessage());
// Return an error response
return response()->json([
'error' => 'An error occurred while processing the request.',
'message' => $e->getMessage()
], 500);
}
}
public function patientFullDetail(Patient $patient)
{
try {
$this->authorizeForUser($this->user, 'edit', new Patient);
$patient->first_name = $patient->first_name . " " . $patient->last_name;
$plans = PatientPlan::join('plans_v1', 'patient_plan.plan_id', '=', 'plans_v1.id')
->leftJoin('medication_categories', 'plans_v1.medication_category_id', '=', 'medication_categories.id')
->where('patient_plan.patient_id', $patient->id)
->select('plans_v1.*', 'medication_categories.category_name')
->orderBy('plans_v1.created_at', 'desc')
->first();
$upcomingMeetings = Appointment::select(
'appointments.patient_id',
'appointments.timezone',
'appointments.appointment_time',
'appointments.appointment_date',
'carts.id as order_id'
)
->leftJoin("carts", "carts.appointment_id", "appointments.id")
->where("appointments.patient_id", $patient->id)
// dd(Constant::getFullSql($upcomingMeetings));
->get();
$completedMeetings = Appointment::select(
'appointments.patient_id',
'appointments.appointment_time',
'appointments.appointment_date',
'appointments.start_time',
'appointments.end_time',
'appointments.timezone',
'telemed_pros.name as provider_name',
'telemed_pros_id as provider_id',
'carts.id as order_id'
)
->leftJoin('telemed_pros', 'telemed_pros.id', 'appointments.telemed_pros_id')
->leftJoin("carts", "carts.appointment_id", "appointments.id")
->where("appointments.patient_id", $patient->id)
->where('appointments.start_time', "!=", null)
->where('appointments.end_time', "!=", null)
->get();
$patientNotes = PatientNote::select(
'patient_notes.id',
'patient_notes.note',
'patient_notes.note_type',
'telemed_pros.name as provider_name',
'telemed_pros.id as provider_id',
'patient_notes.created_at',
'patient_notes.patient_id',
'carts.id as order_id',
'patient_notes.created_by_id',
'patient_notes.created_by_type'
)
->leftJoin('telemed_pros', 'patient_notes.telemed_pros_id', 'telemed_pros.id')
->leftJoin("carts", "carts.appointment_id", "patient_notes.appointment_id")
->where("patient_notes.patient_id", $patient->id)
->get();
foreach ($patientNotes as $notes) {
if ($notes->note_type != 'Notes')
$notes->note = $this->url->to("assets/files/" . $notes->patient_id . ".png");
else
$notes->note = $notes->note;
}
$patientPrescription = PatientPrescription::select(
'patient_prescription.*',
'telemed_pros.name as provider_name',
'prescriptions.*',
'carts.id as order_id'
)
->leftJoin('appointments', 'patient_prescription.appointment_id', 'appointments.id')
->leftJoin("carts", "carts.appointment_id", "appointments.id")
->leftJoin('telemed_pros', 'appointments.telemed_pros_id', 'telemed_pros.id')
->leftJoin('prescriptions', 'prescriptions.id', 'patient_prescription.prescription_id')
->where('patient_prescription.patient_id', $patient->id)->get();
$patient->profile_completion_Percentage = $patient->profile_completion_Percentage;
$labkits = LabkitOrderItem::leftJoin(
'lab_kit',
'labkit_order_items.lab_kit_id',
'lab_kit.id'
)
->leftJoin(
'items',
'items.id',
'labkit_order_items.item_id'
)
->leftJoin(
'plans_v1',
'plans_v1.id',
'items.plans_id'
)
->leftJoin(
'carts',
'carts.id',
'labkit_order_items.cart_id'
)
->where('carts.patient_id', $patient->id)
->select(
'labkit_order_items.id',
'labkit_order_items.status',
'labkit_order_items.result',
'lab_kit.name as lab_kit_name',
'plans_v1.id as product_id',
'plans_v1.title as product_name'
)
->get();
$orderList = Cart::select("appointments.*", 'appointments.id as appointment_id', 'carts.*', 'carts.id as order_id', 'telemed_pros.name as agent_name', 'telemed_pros.email as agent_email')
->leftJoin('appointments', 'appointments.id', 'carts.appointment_id')
->leftJoin('telemed_pros', 'appointments.telemed_pros_id', '=', 'telemed_pros.id')
->where('appointments.patient_id', $patient->id);
$orderListData = $orderList->get();
return response()->json([
'patient' => $patient,
'plans' => $plans,
'upcomingMeetings' => $upcomingMeetings,
'completed_meetings' => $completedMeetings,
'patientNotes' => $patientNotes,
'prescriptionData' => $patientPrescription,
'labkit' => $labkits,
'orderListData' => $orderListData,
]);
} catch (AuthorizationException $e) {
return $e->getMessage();
}
}
public function patientDelete(Patient $patient)
{
try {
$this->authorizeForUser($this->user, 'delete', new Patient);
Patient::where("id", $patient->id)->delete();
return response()->json([
'patient' => "Deleted Successfully"
]);
} catch (AuthorizationException $e) {
return $e->getMessage();
}
}
public function patientUpdate(Patient $patient, Request $request)
{
try {
$this->authorizeForUser($this->user, 'edit', new Patient);
$patient->first_name = $request->input('first_name');
$patient->last_name = $request->input('last_name');
$patient->phone_no = $request->input('phone_no');
$patient->shipping_address = $request->input('gender');
$patient->shipping_address = $request->input('dob');
if ($request->input('password')) {
$patient->password = Hash::make($request->input('password'));
}
$patient->shipping_address = $request->input('address');
$patient->shipping_state = $request->input('state');
$patient->shipping_city = $request->input('city');
$patient->shipping_zipcode = $request->input('zip');
$patient->shipping_country = $request->input('country');
$patient->save();
return response()->json([
'message' => 'Patient updated successfully',
'telemed' => $patient
]);
} catch (AuthorizationException $e) {
return $e->getMessage();
}
}
public function getNotePatient(Patient $patient, Appointment $appointment, Request $request)
{
try {
$this->authorizeForUser($this->user, 'patient_notes', new Patient);
$patientNotes = PatientNote::where("patient_id", $patient->id)
->where("appointment_id", $appointment->id)
->with('appointment')
->get();
$data = $patientNotes->map(function ($patientNote) {
$fileUrl = "/assets/files/{$patientNote->id}.png";
$filePath = public_path($fileUrl);
if (File::exists($filePath)) {
$fileUrl = "/assets/files/{$patientNote->id}.png";
} else {
$fileUrl = null;
}
return [
'id' => $patientNote->id,
'note' => $patientNote->note,
'note_type' => $patientNote->note_type,
'created_at' => $patientNote->created_at,
'patient_id' => $patientNote->patient_id,
'appointment' => $patientNote->appointment,
'telemedPro' => $patientNote->telemedPro,
'file_url' => $fileUrl,
'telemedPro' => $patientNote->appointment?->telemedPro
];
});
return response()->json([
'message' => 'Patient notes retrieved',
'data' => $data
], 200);
} catch (AuthorizationException $e) {
return $e->getMessage();
}
}
public function patient(Patient $patient)
{
return response()->json([
'data' => $patient
], 200);
}
public function getPatientPrescription($patient_id, $appointment_id)
{
try {
$this->authorizeForUser($this->user, 'patinet_prescriptions', new Patient);
$patientPrescription = PatientPrescription::with('prescription')
->where('patient_id', $patient_id)
->where('appointment_id', $appointment_id)
->get();
$prescriptionData = [];
foreach ($patientPrescription as $prescription) {
$prescriptionData[] = [
'patient' => $prescription->patient,
'prescription' => $prescription->prescription,
'created_at' => $prescription->created_at,
'updated_at' => $prescription->updated_at,
'direction_one' => $prescription->direction_one,
'direction_two' => $prescription->direction_two,
'dont_substitute' => $prescription->dont_substitute,
'comments' => $prescription->comments,
'appointment_id' => $prescription->appointment_id,
'status' => $prescription->status,
'appointment' => $prescription->appointment,
'telemedPro' => $prescription->appointment->telemedPro,
'licenseNumber' => LicenseNumberModel::where("provider_id", $patient_id)->orderBy('id', 'DESC')->first()
];
}
if (!$patientPrescription->isEmpty()) {
return response()->json($prescriptionData);
} else {
return response()->json(['message' => 'Prescription not found'], 404);
}
} catch (AuthorizationException $e) {
return $e->getMessage();
}
}
public function storePatientPrescription(Request $request)
{
try {
$this->authorizeForUser($this->user, 'patinet_prescriptions', new Patient);
$cart = Cart::find($request->input("order_id"));
$prescription = PatientPrescription::create($request->all());
$prescription->appointment_id = $cart->appointment_id;
$prescription->status = "pending";
$prescription->save();
$patient = $prescription->patient;
$setting = Setting::find(1);
/* Mail::send('emails.prescriptionAdd', ['patient' => $patient, 'prescription' => $prescription, 'setting' => $setting], function ($message) use ($patient, $user) {
$message->to($patient->email, $patient->first_name)
->subject('New Prescription Details from ' . $user->name);
}); */
return response()->json($prescription, 200);
} catch (AuthorizationException $e) {
return $e->getMessage();
}
}
public function updateStatusPrescription($patient_prescription_id, Request $request)
{
//
try {
$this->authorizeForUser($this->user, 'patinet_prescriptions_edit', new Patient);
$status = $request->input("status");
$prescription = PatientPrescription::find($patient_prescription_id);
$prescription->status = $status;
$prescription->save();
$patient = $prescription->patient;
$setting = Setting::find(1);
/* Mail::send('emails.prescriptionUpdated', ['patient' => $patient, 'setting' => $setting], function ($message) use ($patient) {
$message->to($patient->email, $patient->first_name)
->subject('Prescription updated.');
}); */
return response()->json($prescription, 200);
} catch (AuthorizationException $e) {
return $e->getMessage();
}
}
public function getStatusPrescription($patient_prescription_id)
{
$prescription = PatientPrescription::with(['prescription'])
->findOrFail($patient_prescription_id);
return response()->json($prescription, 200);
}
public function updatePatientPrescription($id, Request $request)
{
try {
$prescription = PatientPrescription::findOrFail($id);
$prescription->update($request->all());
if ($request->has('status')) {
$prescription->status = $request->input('status');
}
$prescription->save();
$patient = $prescription->patient;
$setting = Setting::find(1);
// You might want to add email notification here if needed
return response()->json([
'message' => 'Prescription updated successfully',
'data' => $prescription
], 200);
} catch (AuthorizationException $e) {
return $e->getMessage();
} catch (\Exception $e) {
return response()->json([
'message' => 'An error occurred while updating the prescription',
'error' => $e->getMessage()
], 500);
}
}
public function deletePatientPrescription($id)
{
try {
$prescription = PatientPrescription::findOrFail($id);
$prescription->delete();
return response()->json([
'message' => 'Prescription deleted successfully'
], 200);
} catch (AuthorizationException $e) {
return $e->getMessage();
} catch (\Exception $e) {
return response()->json([
'message' => 'An error occurred while deleting the prescription',
'error' => $e->getMessage()
], 500);
}
}
}