CrestRoad/laravel/app/Http/Controllers/AppointmentController.php

424 lines
20 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\LambdaRequest;
use Commonhelper;
use DB;
use URL;
use Log;
use App\Mail\GeneralEmail;
use Mail;
class AppointmentController extends Controller
{
public function __construct()
{
$this->_service = 'contact';
$this->_module = 'contact';
$this->_viewname = 'appointment';
$this->_title = 'Contact';
$this->_listtype = 'ajaxlist';
$this->_base_url = '/appointment/';
}
public function register(Request $request)
{
$state = Commonhelper::getstate();
$city = Commonhelper::getcity();
return $this->view('form')->with(['state' => $state, 'city' => $city]);
}
public function postregister(Request $request)
{
$post = $request->except('_token');
//$response = LambdaRequest::getrequest('ums', 'contact/get_all', ['source'=> 'dynamodb', 'search' => '{"phone":"'.$post['phone'].'"}' ], env('LAMBDA_ACCESS_TOKEN', 'default_value') );
$petientdata = [
'name' => $post['name'],
'phone' => $post['phone'],
'email' => $post['email'],
'city' => $post['city'],
'state' => $post['state'],
'enrolled_by' => $post['enrolled_by'],
'preferred_language' => $post['preferred_language'],
'inhaler_type' => $post['inhaler_type'],
'consulted_doctor' => $post['consulted_doctor'],
'position' => 'india'
];
// if(count($response->data->items) > 0) {
// $petientdata['id'] = $response->data->items[0]->id;
// $response = LambdaRequest::postrequest('ums', 'contact/update', $petientdata, env('LAMBDA_ACCESS_TOKEN'));
// } else {
// $response = LambdaRequest::postrequest('ums', 'contact/create', $petientdata, env('LAMBDA_ACCESS_TOKEN'));
// }
$data = DB::table('appointments')
->where('phone', $post['phone'])
->get();
date_default_timezone_set('Asia/Calcutta');
$prev_date = '';
if (isset($data)) {
$canRegister = true;
foreach ($data as $value) {
if (($value->patient_status == 'PENDING' || $value->patient_status == 'NOSHOW') && $value->date > date('Y-m-d H:i:s')) {
$prev_date = $value->date;
$canRegister = false;
return redirect($this->_base_url . 'register')->with('error', ['msg' => 'Please complete your previous appointment before registering for a new meeting.', 'prev_date' => $prev_date]);
}
}
if ($canRegister) {
$response = LambdaRequest::postrequest('contact', 'contact/create', $petientdata, env('LAMBDA_ACCESS_TOKEN'));
log::debug(print_r($response->data->item, true));
if ($response->status == 'success') {
$request->session()->put('current_patient', $response->data->item);
return redirect($this->_base_url . 'book')->withSuccess('Successfully registered!!');
} else {
return redirect($this->_base_url . 'register')->with('error', ['msg' => 'Please complete your previous appointment before registering for a new meeting.', 'prev_date' => $prev_date]);
}
}
}
}
public function book(Request $request)
{
$patient = $request->session()->get('current_patient');
//echo '<pre>'; print_r($patient); exit;
return view($this->_viewname . '.book')->with('patient', $patient);
}
protected function _getslots($schedules, $date, $doctor_id)
{
$leaves = DB::table('leaves')->where('status', 'active')->get();
$appointments = DB::table('appointments')
->select('date', 'user_id')
->whereBetween('date', [$date . ' 00:00:00', $date . ' 23:59:59'])
//->where('doctor_id', $doctor_id)
->get();
$slots = [];
$now = strtotime("now") + 60 * 60 * 17;
//$now = strtotime("now");
foreach ($schedules as $schedule) {
$start = str_contains($schedule->start, '.') ? str_replace('.', ':', $schedule->start) : $schedule->start . ':00';
$end = str_contains($schedule->end, '.') ? str_replace('.', ':', $schedule->end) : $schedule->end . ':00';
list($h, $m) = explode(':', $start);
$start = sprintf('%02d', $h) . ':' . substr($m . '00', 0, 2);
list($h, $m) = explode(':', $end);
$end = sprintf('%02d', $h) . ':' . substr($m . '00', 0, 2);
$start = strtotime($date . ' ' . $start);
$end = strtotime($date . ' ' . $end);
while ($start <= $end) {
if ($start + 30 * 60 <= $end) {
$available = true;
foreach ($appointments as $appo) {
if (strtotime($appo->date) == $start && $appo->user_id == $schedule->user_id) {
$available = false;
}
}
foreach ($leaves as $leave) {
if ($leave->date >= $date && $leave->date <= $date && $leave->user_id == $schedule->user_id) {
$available = false;
}
}
if ($start < $now) {
$available = false;
}
if ($available) $slots[] = ['user_id' => $schedule->user_id, 'value' => date("H:i", $start), 'label' => date("h:iA", $start)];
}
$start = $start + 30 * 60;
}
}
$finalslots = [];
$finalslotsTimes = [];
$slotLoad = [];
$usertimeArray = [];
foreach ($slots as $slot) {
$usertimeArray[$slot['value']][] = $slot;
}
foreach ($slots as $slot) {
if (!in_array($slot['value'], $finalslotsTimes)) {
$slt = $usertimeArray[$slot['value']][rand(0, (sizeof($usertimeArray[$slot['value']]) - 1))];
$finalslots[] = $slt;
$finalslotsTimes[] = $slt['value'];
}
}
usort($finalslots, function ($a, $b) {
return strcmp($a['value'], $b['value']);
});
return $finalslots;
}
protected static function _createapptcode()
{
$code = SELF::random_strings(10);
if (DB::table('appointments')->where('code', $code)->exists()) {
$code = SELF::_createapptcode();
}
return $code;
}
protected static function random_strings($length_of_string)
{
$str_result = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
return substr(str_shuffle($str_result), 0, $length_of_string);
}
public function postslots(Request $request)
{
$date = $request->input('date');
$patient = $request->session()->get('current_patient');
$users = DB::table('users')->select('user_id')->where('languages', 'like', '%'.$patient->preferred_language.'%')->get();
//log::debug(print_r($users, true));
$uids = [];
foreach($users as $user) {
$uids[] = $user->user_id;
}
//log::debug(print_r($uids, true));
//$doctor_id = $request->input('doctor_id');
//$slots = Helper::getSlots($date, $doctor_id);
$weekday = date("N", strtotime($date));
$schedules = DB::table('schedule')->wherein('user_id', $uids)->where('weekday', $weekday)->get();
$slots = $this->_getslots($schedules, $date, 0);
return response()->json(['status' => 'success', 'slots' => $slots]);
}
public function postbookslot(Request $request)
{
try {
$post = $request->input();
$patient = $request->session()->get('current_patient');
$weekday = date("N", strtotime($post['date']));
$users = DB::table('users')->select('user_id')->where('languages', 'like', '%'.$patient->preferred_language.'%')->get();
$uids = [];
foreach($users as $user) {
$uids[] = $user->user_id;
}
$schedules = DB::table('schedule')->wherein('user_id', $uids)->where('weekday', $weekday)->get();
$doctor_id = 0;
$slots = $this->_getslots($schedules, $post['date'], $doctor_id);
$selectedSlot = '';
foreach ($slots as $sl) {
if ($sl['value'] == $post['slot']) {
$selectedSlot = $sl;
}
}
$post['patient_id'] = $patient->id;
$post['phone'] = $patient->phone;
$post['doctor_id'] = $doctor_id;
$post['user_id'] = $selectedSlot['user_id'];
//$post['code'] = $invite->patient_id.str_random(8).$invite->doctor_id;
$post['code'] = SELF::_createapptcode();
unset($post['_token']);
$post['date'] = $post['date'] . ' ' . $post['slot'] . ':00';
unset($post['slot']);
$post['updated_at'] = date("Y-m-d H:i:s", strtotime('now'));
$id = DB::table('appointments')->insertGetId($post);
$this->sendApptMessages($id);
// $this->createMeeting($id, $post['user_id']);
return redirect($this->_base_url . 'success');
} catch (Exception $e) {
return redirect($this->_base_url . 'failure');
}
}
public function success()
{
return view($this->_viewname . '.success');
}
public function failure()
{
return view($this->_viewname . '.failure');
}
protected function sendApptMessages($apptid)
{
$appt = DB::table('appointments')->select('code', 'patient_id', 'doctor_id', 'date', 'user_id')->where('id', $apptid)->first();
$patient = $this->_request->session()->get('current_patient');
//echo '<pre>'; print_r($patient); exit;
// $message = 'Hi ' . $patient->name . ', Your video appointment for Pulmocare device with Our Expert is booked for ' . date("j M Y, h:iA", strtotime($appt->date)) . '. Use the link to join the video apppointment ' . URL::to('/meet/') . $appt->code . '. Regards Stratawiz Support';
//self::appointmentmessage($patient->phone, $message);
$template = ["name" => 'appointment_confirmation', "language" => ["code" => "en"]];
$template["components"] = [];
$template["components"][] = ["type" => "body", "parameters" => [["type" => "text", "text" => $patient->name], ["type" => "text", "text" => date("j M Y", strtotime($appt->date))], ["type" => "text", "text" => date("h:iA", strtotime($appt->date))]]];
//$template["components"][] = ["type" => "button", "sub_type" => "URL", "index" => "0", "parameters" => [ ["type" => "payload", "payload" => $appt->code ] ] ];
$params = [
"messaging_product" => "whatsapp",
"to" => "91" . $patient->phone,
"type" => "template",
"template" => $template
];
DB::table('raphiwa_send')->insert(['to' => $patient->phone, 'text' => json_encode($params), 'contact_id' => $patient->id, 'session_id' => $appt->code]);
$data = new \StdClass;
$data->sender_name = 'Rapport Support';
$data->sender_email = 'support@stratawiz.com';
$data->subject = 'Healthylungs New Appointment';
$data->body = '<p>Dear Educator,</p>
<p>A new appointment has been booked for Vitual Educator platform. Please visit the admin panel to view details.</p>
<p>Patient Name: ' . $patient->name . '</p>
<p>Appointment Date & Time: ' . date("j M Y, h:iA", strtotime($appt->date)) . '</p>
';
$user = DB::table('users')->select('email')->where('user_id', $appt->user_id)->first();
//Mail::to(str_replace('alkempsp-', '', $user->email))->cc(['sapna@stratawiz.com', 'ravi@stratawiz.com'])->send(new GeneralEmail($data));
}
protected static function appointmentmessage(string $number, string $text)
{
$number = '91' . substr(preg_replace('/[^A-Za-z0-9]/', '', str_replace(' ', '-', $number)), -10);
$apiKey = urlencode('AyJgziOgT60-GeJskIwvauRH5mWKjMjwsE8VEscZuz');
$message = str_replace('https://', '', $text);
$sender = urlencode('VRTENG');
$message = rawurlencode($message);
$data = array('apikey' => $apiKey, 'numbers' => $number, "sender" => $sender, "message" => $message);
$ch = curl_init('https://api.textlocal.in/send/');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
}
protected function createMeeting($apptid, $user_id) {
$appt = DB::table('appointments')->select('code', 'patient_id', 'doctor_id', 'date', 'patient_details')->where('id', $apptid)->first();
$user = DB::table('users')->select("zoom_email_id","zoom_account_id","zoom_client_id","zoom_client_secret")->where('user_id', $user_id)->first();
$access_token = false;
$client = new \GuzzleHttp\Client();
if(DB::table('zoom_account_credentials')->where('expires_in', '>', strtotime("now") )->where('user_id', $user_id)->count() > 0 ) {
$access_token = DB::table('zoom_account_credentials')->where('expires_in', '>', strtotime("now") )->where('user_id', $user_id)->first();
$access_token = $access_token->access_token;
} else {
$response = $client->post('https://zoom.us/oauth/token?grant_type=account_credentials&account_id='.$user->zoom_account_id, [
'headers' => ['Content-Type' => 'application/json', 'Authorization' => 'Basic '.base64_encode($user->zoom_client_id.':'.$user->zoom_client_secret) ]
]);
if($response->getStatusCode() == 200) {
$access_token = json_decode($response->getBody()->getContents());
DB::table('zoom_account_credentials')->insert(['access_token' => $access_token->access_token, 'expires_in' => (strtotime("now") + $access_token->expires_in - 99), 'user_id' => $user_id ]);
$access_token = $access_token->access_token;
} else {
$access_token = false;
}
}
if($access_token) {
//$patient = $this->_request->session()->get('current_patient');
//echo '<pre>'; print_r($patient); exit;
$patient = json_decode($appt->patient_details);
$params = [
"agenda" => "Pulmocare Device Demo with " . $patient->name . ' at ' . date("h:iA", strtotime($appt->date)),
"default_password" => false,
"duration" => 30,
"password" => "123456",
"pre_schedule" => false,
"host_video" => true,
"meeting_authentication" => false,
"start_time" => str_replace('+05:30', 'Z', date("c", strtotime($appt->date))),
"timezone" => "Asia/Kolkata",
"topic" => "Pulmocare Device Demo with " . $patient->name . ' at ' . date("h:iA", strtotime($appt->date)),
"type" => 2
];
$response = $client->post('https://api.zoom.us/v2/users/'.$user->zoom_email_id.'/meetings', [
'headers' => ['Content-Type' => 'application/json', 'Authorization' => 'Bearer '.$access_token ],
'body' => json_encode($params)
]);
if($response->getStatusCode() == 200 || $response->getStatusCode() == 201) {
$meeting_details = json_decode($response->getBody()->getContents());
DB::table('appointments')->where('code', $appt->code)->update(['zoom_details' => json_encode($meeting_details) ]);
}
}
}
public function meet($code, Request $request)
{
$appt = DB::table('appointments')->select('id', 'user_id', 'code', 'patient_id', 'doctor_id', 'date', 'zoom_details')->where('code', $code)->first();
$meetDetails = json_decode($appt->zoom_details);
if(!isset($meetDetails)) {
$this->createMeeting($appt->id, $appt->user_id);
return redirect('/meet/'.$code);
}
if (strtotime($appt->date) <= strtotime("now") + 60 * 60 * 5.5 && strtotime($appt->date) + 60 * 30 >= strtotime("now") + 60 * 60 * 5.5) {
return redirect($meetDetails->join_url);
} elseif (strtotime($appt->date) + 60 * 30 < strtotime("now") + 60 * 60 * 5.5) {
$response = LambdaRequest::getrequest('contact', 'contact/get_one', ['id' => $appt->patient_id], env('LAMBDA_ACCESS_TOKEN'));
$params = ['current_time' => strtotime("now") + 60 * 60 * 5.5, 'start_time' => strtotime($appt->date), 'end_start' => strtotime($appt->date) + 60 * 30];
$params['join_link'] = $meetDetails->join_url;
$params['patient'] = $response->data->item->name;
$params['missed'] = true;
$params['code'] = $appt->code;
return view($this->_viewname . '.meeting')->with($params);
} else {
$response = LambdaRequest::getrequest('contact', 'contact/get_one', ['id' => $appt->patient_id], env('LAMBDA_ACCESS_TOKEN'));
$params = ['current_time' => strtotime("now") + 60 * 60 * 5.5, 'start_time' => strtotime($appt->date), 'end_start' => strtotime($appt->date) + 60 * 30];
$params['join_link'] = $meetDetails->join_url;
$params['patient'] = $response->data->item->name;
$params['missed'] = false;
return view($this->_viewname . '.meeting')->with($params);
}
}
public function reschedule($code, Request $request)
{
$appt = DB::table('appointments')->select('code', 'patient_id', 'doctor_id', 'date', 'zoom_details')->where('code', $code)->first();
$response = LambdaRequest::getrequest('contact', 'contact/get_one', ['id' => $appt->patient_id], env('LAMBDA_ACCESS_TOKEN', 'default_value'));
$request->session()->put('current_patient', $response->data->item);
//echo '<pre>'; print_r($patient); exit;
return view($this->_viewname . '.book')->with('patient', $response->data->item);
}
public function feedbackform($code, Request $request)
{
$forinfo = LambdaRequest::postrequest('form', 'survey/getrawform', ['partition' => 'rapport-alkempsp', 'form_id' => '1688350537-4c396640-dcf4-48a1-b028-514484c3c6a5']);
$forinfo = $forinfo->data;
//echo '<pre>'; print_r($forinfo); exit;
$request->session()->put('forinfo', $forinfo->form);
//echo '<pre>'; print_r($session); print_r($forinfo); exit;
$data = [
'questions' => $forinfo->questions, 'form' => $forinfo->form, 'form_id' => $forinfo->form->id, 'recipient' => $code
];
return view('road.feedbackform')->with($data);
}
public function postfeedbackform($code, Request $request)
{
$appt = DB::table('appointments')->select('id', 'code', 'patient_id', 'doctor_id', 'user_id', 'date')->where('code', $code)->first();
$user = DB::table('users')->select('name')->where('user_id', $appt->user_id)->first();
$response = LambdaRequest::getrequest('contact', 'contact/get_one', ['id' => $appt->patient_id], env('LAMBDA_ACCESS_TOKEN'));
$post = $request->except('_token');
$forinfo = $request->session()->get('forinfo');
$post['appointment_id'] = $appt->id;
$post['appointment_code'] = $appt->code;
$post['patient_id'] = $appt->patient_id;
$post['patient_name'] = $response->data->item->name;
$post['user_id'] = $appt->user_id;
$post['user_name'] = $user->name;
$post['appointment_date'] = $appt->date;
//$response = LambdaRequest::postrequest('ums', 'contact/update', ['id' => $post['recipient'], 'feedback' => 'yes', 'position' => 'india'], env('LAMBDA_ACCESS_TOKEN', 'default_value'));
//echo '<pre>'; print_r($post); exit;
$finfo = LambdaRequest::postrequest('form', 'survey/submitform', ['formdata' => $post, 'entity_id' => $forinfo->id, 'partition' => 'rapport-alkempsp', 'user_id' => $appt->user_id]);
//dd($finfo);
return view('road.feedbackformsuccess');
//echo '<pre>'; print_r($finfo); print_r($post); print_r($forinfo); exit;
}
}