Server : Apache System : Linux 145.162.205.92.host.secureserver.net 5.14.0-611.45.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Apr 1 05:56:53 EDT 2026 x86_64 User : tradze ( 1001) PHP Version : 8.1.34 Disable Function : NONE Directory : /home/tradze/www/app/Modules/Users/Http/Controllers/Frontend/ |
<?php
namespace App\Modules\Users\Http\Controllers\Frontend;
use App\Http\Controllers\SiteController;
use App\Modules\Postcodes\Models\Postcode;
use App\Modules\Schedules\Models\BookingOrder;
use App\Modules\Schedules\Repositories\BookingRepository;
use App\Modules\Services\Models\ServiceDuration;
use App\Modules\Services\Models\SalonServiceDuration;
use App\Modules\Services\Models\ServiceType;
use App\Modules\Users\Http\Requests\ClientMessageUpdRequest;
use App\Modules\Users\Models\UserLocation;
use App\Modules\Users\Repositories\MessageThreadRepository;
use App\User;
use Carbon\Carbon;
use Cmgmyr\Messenger\Models\Message;
use Cmgmyr\Messenger\Models\Participant;
use Cmgmyr\Messenger\Models\Thread;
use GoogleMaps\GoogleMaps;
use Illuminate\Http\Request;
use App\Modules\Users\Models\UserAddress;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Session;
use App\Modules\Testimonials\Models\SalonReviews;
use Illuminate\Support\Facades\Http;
use GuzzleHttp\Client;
class AccountBookingsController extends SiteController
{
/**
* User address book
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
// dd('stop');
//get user
$user = User::find(\Auth::user()->id);
//get upcoming user bookings
$bookings = $user->bookings()
->select('*', DB::raw('CONCAT_WS(" ",date,hour) as bookingdate'))
->whereRaw(' TIMESTAMPADD(MINUTE,duration_min,CONCAT_WS(" ",date,hour)) >= TIMESTAMP(DATE_SUB(NOW(),INTERVAL 1 HOUR))')
// ->whereRaw(' CONCAT_WS(" ",date,hour) >= NOW()')
// ->whereRaw("date >= DATE(NOW()) AND TIME(ADDTIME(TIME(hour),'0 1:0:0')) > TIME(hour)")
// ->whereRaw('ADDTIME(ADDTIME(hour,STR_TO_DATE(CONCAT(FLOOR(duration_min/60),\':\',MOD(duration_min,60)),"%h:%i")),"0:15") > TIME(NOW())')
// ->where('salon_id', null)
->where('is_active', 1)
->orderBy('date', 'asc')
->orderBy('hour', 'asc')
->get();
// dd($bookings);
$upcoming = $bookings->first();
// $bookingInfo = json_decode($upcoming['orderInfo']);
//
$i = 0;
foreach ($bookings as $key => $booking) {
if ($booking->salon_id) {
// dd($booking->orderInfo);
$infos = json_decode($booking->orderInfo, true);
// dd($infos);
// foreach($infos as $key => $info){
// dd($infos['duration_id']);
$var = SalonServiceDuration::where('id', $infos['duration_id'])->get();
// $var['booking_id'] = $booking->id;
$booking['duraton'] = $var;
// }
} else {
$info = json_decode($booking->orderInfo, true);
$var = ServiceDuration::where('id', $info['duration_id'])->get();
// $var['booking_id'] = $booking->id;
$booking['duraton'] = $var;
}
$i++;
}
//create data array
$data['bookings'] = $bookings;
$data['extensions'] = ServiceDuration::where('is_extra', 1)->orderBy('duration', 'asc')->get();
$data['upcoming'] = $upcoming;
$data['booking'] = Session::get('booking');
//render page
return view('users::frontend_new.bookings', $data);
}
protected function gTimeTravel($from, $to, $mode = "DRIVING")
{
$params = [
'origin' => $from,
'destination' => $to,
'mode' => $mode,
'departure_time' => 'now',
];
$direction = \GoogleMaps::load('directions')
->setParam($params)
->get();
$time = json_decode($direction, true);
if ($time['status'] != "OK")
return null;
//get estimated time arrival in minutes
// $buffer = 5;
$buffer = 0;
$eta = ceil($time['routes'][0]['legs'][0]['duration']['value'] / 60) + $buffer;
//return eta
return $eta;
}
public function pastSalonBookings()
{
//get user
$user = User::find(\Auth::user()->id);
//get upcoming user bookings
$bookings = $user->bookings()
->select('*', DB::raw('CONCAT_WS(" ",date,hour) as bookingdate'))
->whereRaw('CONCAT_WS(" ",date,hour) < NOW()')
// ->whereHas('booking',function($query){
// return $query->where('is_active',1);
// })
->orderBy('created_at', 'desc')
->take(15)
->get();
// dd($bookings);
$upcoming = $bookings->first();
$i = 0;
foreach ($bookings as $key => $booking) {
$booking['is_review'] = 0;
$reviews = SalonReviews::where('user_id', Auth::user()->id)->where('booking_id', $booking->id)->get();
if (count($reviews)) {
$booking['is_review'] = 1;
}
if ($booking->salon_id) {
$infos = json_decode($booking->orderInfo, true);
// dd($infos);
// foreach($infos as $key => $info){
// dd($infos['duration_id']);
$var = [];
if (!empty($info['duration_id'])) {
$var = SalonServiceDuration::where('id', $info['duration_id'])->get();
}
// $var['booking_id'] = $booking->id;
$booking['duraton'] = $var;
// }
} else {
$info = json_decode($booking->orderInfo, true);
// dd($info);
$var = [];
if (!empty($info['duration_id'])) {
$var = ServiceDuration::where('id', $info['duration_id'])->get();
}
// $var['booking_id'] = $booking->id;
$booking['duraton'] = $var;
}
$i++;
}
//create data array
$data['bookings'] = $bookings;
// dd($bookings);
$data['extensions'] = ServiceDuration::where('is_extra', 1)->orderBy('duration', 'asc')->get();
$data['upcoming'] = $upcoming;
$data['booking'] = Session::get('booking');
//render page
return view('users::frontend_new.past_bookings', $data);
}
/**
* Track therapist
* @param $id
*/
public function track_therapist(BookingOrder $booking)
{
$user = User::find(\Auth::user()->id);
if ($booking->user_id != $user->id)
abort(403, 'Unauthorized action.');
//create data array
$data['booking'] = $booking;
$data['therapist'] = [
'geo' => [
'lat' => 51.401392,
'lng' => 0.014948
],
];
$destination = json_decode($booking->orderInfo, true)['locationGeo'];
$bookingInfo = json_decode($booking->orderInfo);
//
//
// $direction = \GoogleMaps::load('directions')
// ->setParam([
// 'origin' => '51.401392,0.014948',
// 'destination' => "{$destination['lat']},{$destination['lng']}",
// "destination" => "51.4152072,0.0292294",
// 'mode' => 'driving',
// 'departure_time' => 'now',
// ])
// ->get();
// $time = json_decode($direction,true);
// dd($time);
// dd($time['routes'][0]['legs'][0]);
if ($bookingInfo->therapistIds) {
$therapistId = $bookingInfo->therapistIds[0];
$data['therapist']['id'] = $therapistId;
$location = UserLocation::where('user_id', $therapistId)->first();
$fromGeo = [
'lat' => $location->lat,
'lng' => $location->lng
];
//compose from coordinates
$from = "{$fromGeo['lat']},{$fromGeo['lng']}";
$address = "{$booking['address']}, London UK";
$response = \GoogleMaps::load('geocoding')
->setParam(['address' => $address])
->get('results');
if (empty($response['results'])) {
$to = $address;
} else {
$toGeo = $response['results'][0]['geometry']['location'];
$to = "{$toGeo['lat']},{$toGeo['lng']}";
}
$eta = $this->gTimeTravel($from, $to);
// if (!$eta || $eta > 60)
// return null;
//add booking buffer for reservation process: equivalent with the availability in the basket
// $eta+=15;
$eta += 2;
$eta = Carbon::now()->addMinutes($eta)->format('H:i');
} else {
$eta = null;
}
$bookdate= Carbon::createFromFormat('Y-m-d H:i',$booking->date->format('Y-m-d').' '.$eta);
$remaining_time = $bookdate->diffInSeconds(null,false)*(-1);
if ($remaining_time<0)
$remaining_time=0;
$data['remaining_time_in_sec'] = $remaining_time;
return view('users::frontend_new.track_therapist', $data);
}
/**
* Get therapist position
*/
public function get_position(BookingOrder $booking)
{
$therapist = $booking->therapists()->first();
//create array position
$location = UserLocation::where('user_id', $therapist->id)->first();
// $location = UserLocation::first();
if (!$location)
return response('Location is not available', 403);
$pos = [
'lat' => $location->lat,
'lng' => $location->lng
];
return $pos;
}
/**
* Message thread for the booking
* @param $id
*/
public function message(BookingOrder $booking)
{
//get thread
$subject = $booking->treadsubject;
$thread = Thread::where('subject', $subject)->first();
//if thread exists, mark it as read
if ($thread)
$thread->markAsRead(Auth::user()->id);
//create data array
$data['thread'] = $thread;
$data['booking'] = $booking;
$data['info'] = json_decode($booking->orderInfo, true);
$data['allMessages'] = $thread ? $thread->messages()->orderBy('created_at', 'asc')->get() : [];
// dd($thread->messages()->orderBy('created_at', 'asc')->get());
//render page
return view('users::frontend_new.booking_message', $data);
}
/**
* Save message thread
* @param BookingOrder $booking
*/
public function save_message(ClientMessageUpdRequest $request, BookingOrder $booking)
{
$input = $request->all();
$subject = $booking->treadsubject;
$thread = Thread::where('subject', $subject)->first();
//begin transaction
DB::beginTransaction();
//create the thread if not exists
if (!$thread) {
$thread = Thread::create(
[
'subject' => $subject,
]
);
} //endif
// create message
Message::create(
[
'thread_id' => $thread->id,
'user_id' => Auth::user()->id,
'body' => $input['message'],
]
);
// Add replier as a participant
$participant = Participant::firstOrCreate(
[
'thread_id' => $thread->id,
'user_id' => Auth::user()->id,
]
);
$participant->last_read = new Carbon;
$participant->save();
//add recipients: is this case the recipients are the therapists
foreach ($booking->therapists as $rec)
$recipients[] = $rec->id;
if (!empty($recipients))
$thread->addParticipant($recipients);
if ($thread) {
DB::commit();
//send message to participants
$threadRepo = new MessageThreadRepository($thread);
$threadRepo->new_message_participants(Auth::user()->id);
} else {
DB::rollBack();
}
// Notify Node.js socket server
// try {
// $client = new Client();
// $socketBaseUrl = env('SOCKET_BASE_URL');
// $response = $client->post($socketBaseUrl . '/chats/send-message', [
// 'json' => [
// 'sender_name' => Auth::user()->profile->first_name,
// 'sender_id' => Auth::user()->id,
// 'receiver_id' => $request->receiver_id,
// 'message' => $request->message,
// 'conversation_id' => $thread->id,
// 'avatar' => asset('/images/'. Auth::user()->profile->avatar)
// ]
// ]);
// $result = $response->getBody()->getContents();
// } catch (\Exception $e) {
// \Log::error('Socket notify failed: ' . $e->getMessage());
// }
return response()->json(['success' => true],200);
//redirect to thread page
return redirect(route('account.profile.mybookings_edit', ['booking' => $booking->id]));
}
/**
* Cancel booking
* @param $id
*/
public function cancel(BookingOrder $booking)
{
//user can cancel only his bookings
if ($booking->user_id != \Auth::user()->id)
return false;
//get booking
//refund booking value
$repo = new BookingRepository();
$refund = $repo->cancel_order($booking);
//return response
return response(['success' => true, 'message' => $refund['message']], 200);
}
}