_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 '
'; 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 '
'; 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 = '

Dear Educator,

A new appointment has been booked for Vitual Educator platform. Please visit the admin panel to view details.

Patient Name: ' . $patient->name . '

Appointment Date & Time: ' . date("j M Y, h:iA", strtotime($appt->date)) . '

'; $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 '
'; 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 '
'; 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 '
'; print_r($forinfo); exit;
        $request->session()->put('forinfo', $forinfo->form);
        //echo '
'; 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 '
'; 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 '
'; print_r($finfo); print_r($post); print_r($forinfo); exit;
    }
}