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/public_html/test.tradze.com/app/Modules/Schedules/Repositories/ |
<?php
namespace App\Modules\Schedules\Repositories;
use App\Modules\Invoices\Repositories\BookingInvoiceRepository;
use App\Modules\Schedules\Models\BookingOrder;
use App\Modules\Schedules\Models\Schedule;
use App\Modules\Postcodes\Models\Postcode;
use App\Modules\Services\Models\ServiceDuration;
use App\Modules\Services\Models\SalonServiceDuration;
use App\Modules\Services\Models\SalonCategory;
use App\Modules\Services\Models\ServiceType;
use App\Modules\Users\Repositories\MessageThreadRepository;
use App\Modules\Vouchers\Models\Voucher;
use App\Modules\Vouchers\Repositories\VoucherRepository;
use App\User;
use App\Modules\Services\Models\FocalPoint;
use App\Modules\Schedules\Models\ScheduleDaysOff;
use Bican\Roles\Models\Role;
use Braintree\Transaction;
use Carbon\Carbon;
use Cmgmyr\Messenger\Models\Message;
use Cmgmyr\Messenger\Models\Participant;
use Cmgmyr\Messenger\Models\Thread;
use GoogleMaps\GoogleMaps;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Session;
use Mockery\CountValidator\Exception;
use App\Modules\Notifications\Facades\NotifRepository;
use Omnipay\Omnipay;
use App\Modules\Users\Models\UserServiceDuration;
use App\Modules\Schedules\Models\BasketTherapist;
use App\Modules\Schedules\Models\BasketVoucher;
use App\Modules\Users\Models\UserCoverageArea;
class BookingClass
{
var $defaultServiceDuration = null;
var $defaultSalonServiceDuration = null;
public function __construct($defaultSalonServiceDuration = null)
{
$this->defaultServiceDuration = ServiceDuration::where('is_default', 1)->first();
if ($defaultSalonServiceDuration != null)
$this->defaultSalonServiceDuration = SalonServiceDuration::where('id', $defaultSalonServiceDuration)->first();
}
/**
* Get available therapists
* @return array
*/
public function therapists()
{
$booking = Session::get('booking');
// dd($booking);
$users = collect();
//if one of mandatory fields is missing, return empty array results
$mandatory_fields = ['duration', 'massage', 'date', 'address'];
foreach ($mandatory_fields as $field) {
if (!isset($booking[$field]))
return $users;
} //endforeach
;
//get postcode zone
// $postcode = Postcode::where('postcode', $booking['postcode'])->first();
//users are not available for the past dates
$today = Carbon::today();
$dateC = Carbon::createFromFormat('Y-m-d', $booking['date']);
$diff = $today->diffInHours($dateC, false);
if ($diff < 0)
return $users;
//query therapists
DB::enableQueryLog();
$users = User::OfTherapists()
->with('servicetypes', 'mywork', 'reviews', 'therapistreview', 'stripeSubscription', 'userDoc')
// ->whereHas('stripeSubscription', function ($query) {
// $query->whereDate('expire_date', '<', Carbon::now());
// })
// ->whereHas('userDoc', function ($query) {
// $query->where('is_approved', 1);
// })
// Only include users who have documents
// ->whereHas('userDoc')
// Exclude users who have any unapproved document
->whereDoesntHave('userDoc', function ($query) {
$query->where('is_approved', 0);
})
->whereHas('servicetypes', function ($query) use ($booking) {
if (isset($booking['massage']) && $booking['massage'] > 0)
$query->where('users_servicetype.servicetype_id', $booking['massage']);
return $query;
})
// ->whereHas('zones', function ($query) use ($postcode) {
// $query->where('users_area_coverage.zone_id', $postcode->zone_id);
// return $query;
// })
->whereHas('workingdays', function ($query) use ($booking) {
$weekday = date('w', strtotime($booking['date']));
$hour = $booking['hour'] . ':00';
$duration = ServiceDuration::find($booking['duration'])->duration;
$hourEnd = Carbon::createFromFormat('H:i:s', $hour)->addMinutes($duration)->format('H:i:s');
if (strtotime($hour) > strtotime($hourEnd))
return $query->where('id', '-1');
$query->where('dayoff', 0);
$query->where('weekday', $weekday);
$query->whereRaw("TIME(STR_TO_DATE(bo_start, '%H:%i')) <= TIME(STR_TO_DATE('{$hour}','%H:%i')) and TIME(STR_TO_DATE(bo_end, '%H:%i')) >= TIME(STR_TO_DATE('{$hourEnd}','%H:%i'))");
return $query;
})
// ->whereDoesntHave('daysoff', function ($query) use ($booking) {
// if (!isset($booking['hour']))
// return $query;
//
// $dateHour = $booking['date'].' '.$booking['hour'].':00';
// $query->whereRaw("STR_TO_DATE('{$dateHour}','%Y-%m-%d %H:%i') between date_start and date_end");
// return $query;
// })
->whereDoesntHave('daysoff', function ($query) use ($booking) {
if (!isset($booking['hour']))
return $query;
$duration = ServiceDuration::find($booking['duration'])->duration;
$duration = $duration - 1;
$dateHour = $booking['date'] . ' ' . $booking['hour'] . ':00';
$dateHourEnd = $booking['date'] . ' ' . date('H:i', strtotime($booking['hour'] . "+{$duration} minutes")) . ':00';
$query->whereRaw('STR_TO_DATE("' . $dateHour . '","%Y-%m-%d %H:%i") > date_start and date_end > STR_TO_DATE("' . $dateHour . '","%Y-%m-%d %H:%i")')
->orWhereRaw('STR_TO_DATE("' . $dateHourEnd . '","%Y-%m-%d %H:%i") > date_start and date_end > STR_TO_DATE("' . $dateHourEnd . '","%Y-%m-%d %H:%i")');
//dd($dateHour,$dateHourEnd);
return $query;
})
->orderBy('nr_crt')
->get()
->filter(function ($user) {
return $user->is_subscribed == true;
})
->values();
// dd($users[0]->is_subscribed);
//unselect unavailable selected users
if (isset($booking['selected_therapists'])) {
$usersAvailable = [];
foreach ($users as $usr)
$usersAvailable[] = $usr->id;
foreach ($booking['selected_therapists'] as $key => $selected) {
if (!in_array($selected, $usersAvailable))
unset($booking['selected_therapists'][$key]);
}
Session::put('booking', $booking);
}
if (isset($booking['hour']) && isset($booking['duration'])) {
$duration = ServiceDuration::find($booking['duration']);
$bufferMin = 55;
$buffer = $duration->duration + 55;
foreach ($users as $key => $u) {
//remove user is he has already a booking at selected date&hour + duration interval
$count = $u->therapistbookings()
->where('date', $booking['date'])
->where(function ($query) use ($booking, $duration, $buffer, $bufferMin) {
return $query->whereRaw('
TIME("' . $booking['hour'] . '") BETWEEN SUBTIME(`hour`,STR_TO_DATE(CONCAT(FLOOR(' . $buffer . '/60),\':\',MOD(' . $buffer . ',60)),"%h:%i:%s")) AND ADDTIME(`hour`,STR_TO_DATE(CONCAT(FLOOR((duration+' . $bufferMin . ')/60),\':\',MOD((duration+' . $bufferMin . '),60)),"%h:%i:%s"))
');
})
->whereHas('booking', function ($query) {
return $query->where('is_active', 1);
})
->count();
if ($count) $users->forget($key);
$countSession = $u->sessionBlockedTherapists()
->where('date', $booking['date'])
->where(function ($query) use ($booking, $duration, $buffer, $bufferMin) {
return $query->whereRaw('
`hour` between SUBTIME("' . $booking['hour'] . '",STR_TO_DATE(CONCAT(FLOOR(' . $buffer . '/60),\':\',MOD(' . $buffer . ',60)),"%h:%i:%s")) and ADDTIME(ADDTIME("' . $booking['hour'] . '",STR_TO_DATE(CONCAT(FLOOR(' . $buffer . '/60),\':\',MOD(' . $buffer . ',60)),"%h:%i:%s")),"0:00:00")
OR
ADDTIME(`hour`, STR_TO_DATE(CONCAT(FLOOR(duration_min/60),\':\',MOD(duration_min,60)),"%h:%i:%s")) BETWEEN SUBTIME("' . $booking['hour'] . '", "00:55:00") AND ADDTIME(ADDTIME("' . $booking['hour'] . '",STR_TO_DATE(CONCAT(FLOOR(' . $buffer . '/60),\':\',MOD(' . $buffer . ',60)),"%h:%i:%s")),"0:00:00")
');
})
->count();
// dd($countSession);
if ($countSession) $users->forget($key);
} //end foreach
} //endif
$usersAvailable = [];
//unselect unavailable selected users
//if (isset($booking['selected_therapists'])){
foreach ($users as $usr)
$usersAvailable[] = $usr->id;
if (isset($booking['selected_therapists'])) {
foreach ($booking['selected_therapists'] as $key => $selected) {
if (!in_array($selected, $usersAvailable))
unset($booking['selected_therapists'][$key]);
}
}
Session::put('booking', $booking);
//}
// dd($usersAvailable);
$usersUnAvailable = User::OfTherapists()
->with('servicetypes', 'mywork', 'stripeSubscription', 'userDoc')
// ->whereHas('stripeSubscription', function ($query) {
// $query->whereDate('expire_date', '>', Carbon::now());
// })
// ->whereHas('userDoc', function ($query) {
// $query->where('is_approved', 1);
// })
// Only include users who have documents
// ->whereHas('userDoc')
// Exclude users who have any unapproved document
->whereDoesntHave('userDoc', function ($query) {
$query->where('is_approved', 0);
})
->whereNotIn('id', $usersAvailable)
->whereHas('servicetypes', function ($query) use ($booking) {
if (isset($booking['massage']) && $booking['massage'] > 0)
$query->where('users_servicetype.servicetype_id', $booking['massage']);
return $query;
})
// ->whereHas('zones', function ($query) use ($postcode) {
// $query->where('users_area_coverage.zone_id', $postcode->zone_id);
// return $query;
// })
->orderBy('nr_crt')
->get()
->filter(function ($user) {
return $user->is_subscribed == true;
})
->values();
// session Address
$addr_longitude = '';
$addr_latitude = '';
$address = $booking['address'];
if (!empty($address)) {
//Formatted address
$formattedAddr = str_replace(' ', '+', $address);
//Send request and receive json data by address
$geocodeFromAddr = file_get_contents('https://maps.googleapis.com/maps/api/geocode/json?address=' . $formattedAddr . '&sensor=false&key=' . config("googlemaps.key"));
$output = json_decode($geocodeFromAddr);
//Get latitude and longitute from json data
$addr_longitude = !empty($output->results[0]->geometry->location->lat) ? $output->results[0]->geometry->location->lat : '';
$addr_latitude = !empty($output->results[0]->geometry->location->lng) ? $output->results[0]->geometry->location->lng : '';
}
// check available users in coverage locations
$available_user_results = array();
if (!empty($users)) {
foreach ($users as $th) {
$is_in_polygon = 0;
$therapist_coverages_1 = UserCoverageArea::where('user_id', $th->id)->get();
$therapist_coverages_last = UserCoverageArea::where('user_id', $th->id)->orderBy('id', 'DESC')->first();
if (!empty($therapist_coverages_last->polygon_no)) {
foreach ($therapist_coverages_1 as $thp_cover) {
//for ($i = 0; $i <= $therapist_coverages_last->polygon_no; $i++) {
$therapist_coverages = UserCoverageArea::select('lng', 'lat')->where('user_id', $th->id)->where('polygon_no', $thp_cover->polygon_no)->get();
$polygon_lat_lng_Arr = array();
foreach ($therapist_coverages as $coverages) {
$longitude = $coverages->lng;
$latitude = $coverages->lat;
$polygon_lat_lng_Arr[] = $longitude . ' ' . $latitude;
}
$longitude_x = $addr_longitude; // x-coordinate of the point to test
$latitude_y = $addr_latitude; // y-coordinate of the point to test
// echo $point = $longitude_x.' '.$latitude_y;
$point = $latitude_y . ' ' . $longitude_x;
//print_r($polygon_lat_lng_Arr);
if (UserCoverageArea::pointInPolygon($point, $polygon_lat_lng_Arr)) {
$is_in_polygon++;
}
// echo $is_in_polygon;
}
}
if (!empty($addr_longitude) && !empty($addr_latitude)) {
if ($is_in_polygon > 0) {
$is_in_polygon = 0;
$user_profile = DB::table("users_profile")->where("user_id", $th->id)->first();
// dd("here");
if ($user_profile->massage_me_now) {
$available_user_results[] = $th;
}
}
}
}
}
// dd($available_user_results);
// check unavailable users in coverage locations
$unavailable_user_results = array();
if (!empty($usersUnAvailable)) {
$is_in_polygon = 0;
foreach ($usersUnAvailable as $th) {
$therapist_coverages_1 = UserCoverageArea::where('user_id', $th->id)->get();
$therapist_coverages_last = UserCoverageArea::where('user_id', $th->id)->orderBy('id', 'DESC')->first();
if (!empty($therapist_coverages_last->polygon_no) && !empty($therapist_coverages_1)) {
foreach ($therapist_coverages_1 as $thp_cover) {
//for ($i = 0; $i <= $therapist_coverages_last->polygon_no; $i++) {
$therapist_coverages = UserCoverageArea::select('lng', 'lat')->where('user_id', $th->id)->where('polygon_no', $thp_cover->polygon_no)->get();
$polygon_lat_lng_Arr = array();
foreach ($therapist_coverages as $coverages) {
$longitude = $coverages->lng;
$latitude = $coverages->lat;
$polygon_lat_lng_Arr[] = $longitude . ' ' . $latitude;
}
$longitude_x = $addr_longitude; // x-coordinate of the point to test
$latitude_y = $addr_latitude; // y-coordinate of the point to test
//echo $point = $longitude_x.' '.$latitude_y;
$point = $latitude_y . ' ' . $longitude_x;
//print_r($polygon_lat_lng_Arr);
if (UserCoverageArea::pointInPolygon($point, $polygon_lat_lng_Arr)) {
$is_in_polygon++;
}
//echo $is_in_polygon;
}
}
if (!empty($addr_longitude) && !empty($addr_latitude)) {
if ($is_in_polygon > 0) {
$is_in_polygon = 0;
$user_profile = DB::table("users_profile")->where("user_id", $th->id)->first();
if ($user_profile->massage_me_now) {
$unavailable_user_results[] = $th;
}
}
}
}
}
$allUsers = array();
// dd($allUsers);
if ($available_user_results) {
$allUsers['available'] = $available_user_results;
}
if ($unavailable_user_results) {
$allUsers['unavailable'] = $unavailable_user_results;
}
//return results
return $allUsers;
}
/**
* Get available therapists right now based on their location and google time travel estimation
* @return array
*/
public function therapistsNow()
{
$users = collect();
$booking = Session::get('booking');
$booking['date'] = Carbon::today()->format('Y-m-d');
$booking['hour'] = Carbon::today()->format('H:i');
//check if the current date is marked as day off
$daysOff = $this->days_off($booking['date']);
if ($daysOff->count())
return $users;
//get weekday working hours: if weekday is non working day, return
$weekday = date('w', strtotime($booking['date']));
$whours = Schedule::where('weekday', $weekday)->where('open', 1)->first();
if (!$whours)
return $users;
//the therapists can be booked only in working hours of the weekday
if (strtotime($whours->bo_end) < strtotime(date('H:i')))
return $users;
//if the start working day hour is bigger then the current hour, return no therapists
if (strtotime($whours->bo_start) > strtotime(date('H:i')))
return $users;
//if the current hour + desired massage duration exceed closing time, return no therapists
if (isset($booking['duration'])) {
$checkduration = ServiceDuration::find($booking['duration'])->duration;
if (strtotime($whours->bo_end) < strtotime(date('H:i') . "+{$checkduration} minutes"))
return $users;
}
//if one of mandatory fields is missing, return empty array results
$mandatory_fields = ['duration', 'massage', 'date'];
foreach ($mandatory_fields as $field) {
if (!isset($booking[$field]))
return $users;
} //endforeach
//get postcode zone
// $postcode = Postcode::where('postcode',$booking['postcode'])->first();
//users are not available for the past dates
$today = Carbon::today();
$dateC = Carbon::createFromFormat('Y-m-d', $booking['date']);
$diff = $today->diffInHours($dateC, false);
if ($diff < 0)
return $users;
//query therapists
// DB::enableQueryLog();
$users = User::OfTherapists()
->with('servicetypes', 'stripeSubscription', 'userDoc')
->whereDoesntHave('userDoc', function ($query) {
$query->where('is_approved', 0);
})
->where('is_book_now', 1)
->whereHas('servicetypes', function ($query) use ($booking) {
if (isset($booking['massage']) && $booking['massage'] > 0)
$query->where('users_servicetype.servicetype_id', $booking['massage']);
return $query;
})
// ->whereHas('zones', function ($query) use ($postcode) {
// $query->where('users_area_coverage.zone_id', $postcode->zone_id);
// return $query;
// })
->whereHas('workingdays', function ($query) use ($booking) {
$weekday = date('w', strtotime($booking['date']));
$hour = Carbon::now()->format('H:i:s');
$duration = ServiceDuration::find($booking['duration'])->duration;
$hourEnd = Carbon::createFromFormat('H:i:s', $hour)->addMinutes($duration)->format('H:i:s');
if (strtotime($hour) > strtotime($hourEnd))
return $query->where('id', '-1');
// dd($hour);
$query->where('dayoff', 0);
$query->where('weekday', $weekday);
$query->whereRaw("TIME(STR_TO_DATE(bo_start, '%H:%i')) <= TIME(STR_TO_DATE('{$hour}','%H:%i')) and TIME(STR_TO_DATE(bo_end, '%H:%i')) >= TIME(STR_TO_DATE('{$hourEnd}','%H:%i'))");
return $query;
})
// ->whereHas('profile', function ($query) {
// $query->where('massage_me_now', 1);
// return $query;
// })
->whereDoesntHave('daysoff', function ($query) use ($booking) {
// if (!isset($booking['hour']))
// return $query;
$hour = Carbon::now()->format('H:i');
$duration = ServiceDuration::find($booking['duration'])->duration;
$dateHour = $booking['date'] . ' ' . $hour . ':00';
$dateHourEnd = $booking['date'] . ' ' . date('H:i', strtotime($hour . "+{$duration} minutes")) . ':00';
$query->whereRaw('STR_TO_DATE("' . $dateHour . '","%Y-%m-%d %H:%i") between date_start and date_end')
->orWhereRaw('STR_TO_DATE("' . $dateHourEnd . '","%Y-%m-%d %H:%i") between date_start and date_end');
// $query->whereRaw('STR_TO_DATE("'.$dateHour.'","%Y-%m-%d %H:%i") between SUBTIME(SUBTIME(date_start,STR_TO_DATE(CONCAT(FLOOR('.$duration.'/60),\':\',MOD('.$duration.',60)),"%h:%i:%s")),"0:15:00") and ADDTIME(ADDTIME(date_end,STR_TO_DATE(CONCAT(FLOOR('.$duration.'/60),\':\',MOD('.$duration.',60)),"%h:%i:%s")),"0:15:00")');
return $query;
})
->whereHas('geoLocation', function ($query) use ($booking) {
$query->whereRaw("DATE('" . date('Y-m-d') . "') between DATE(updated_at) and DATE(updated_at)");
return $query;
})
->whereHas('geoLocation', function ($query) use ($booking) {
$query->whereRaw('"' . date('H:i:0') . '" between SUBTIME(TIME(updated_at),"02:30:00") and ADDTIME(TIME(updated_at),"02:30:00")');
return $query;
})
->where(function ($query) use ($booking) {
$query
->whereDoesntHave('therapistbookings', function ($query) use ($booking) {
$duration = ServiceDuration::find($booking['duration']);
// $buffer = $duration->duration+0;
$bufferMin = 55;
$buffer_before = $duration->duration + 31;
$buffer = $duration->duration + $bufferMin;
$buffer_as_time_before = floor($buffer_before / 60) . ':' . ($buffer_before % 60);
$buffer_as_time = floor($buffer / 60) . ':' . ($buffer % 60);
$query
->where('date', date('Y-m-d'))
->where(function ($query) use ($booking, $duration, $buffer, $bufferMin) {
return $query->whereRaw('
TIME("' . date('H:i') . '") BETWEEN SUBTIME(`hour`,STR_TO_DATE(CONCAT(FLOOR(' . $buffer . '/60),\':\',MOD(' . $buffer . ',60)),"%h:%i:%s")) AND ADDTIME(`hour`,STR_TO_DATE(CONCAT(FLOOR((duration+' . $bufferMin . ')/60),\':\',MOD((duration+' . $bufferMin . '),60)),"%h:%i:%s"))
');
})
->whereHas('booking', function ($query) {
return $query->where('is_active', 1);
});
// $query->where('date',date('Y-m-d'))
// ->whereRaw('`hour` between SUBTIME("'.date('H:i').'","'.$buffer_as_time_before.'") and ADDTIME(ADDTIME("'.date('H:i').'",STR_TO_DATE(CONCAT(FLOOR('.$duration->duration.'/60),\':\',MOD('.$duration->duration.',60)),"%h:%i")),"'.$buffer_as_time.'")')
//// ->whereRaw('`hour` between SUBTIME(hour,"'.$buffer_as_time_before.'") and ADDTIME(ADDTIME(hour,STR_TO_DATE(CONCAT(FLOOR(duration/60),\':\',MOD(duration,60)),"%h:%i")),"'.$buffer_as_time.'")')
//// ->whereRaw('`hour` between SUBTIME("'.date('H:i').'","00:00") and ADDTIME(ADDTIME("'.date('H:i').'",STR_TO_DATE(CONCAT(FLOOR('.$duration->duration.'/60),\':\',MOD('.$duration->duration.',60)),"%h:%i")),"'.$buffer_as_time.'")')
// ->whereHas('booking',function($query){
// return $query->where('is_active',1);
// });
return $query;
})
->where(function ($query) use ($booking) {
$query->whereDoesntHave('sessionBlockedTherapists', function ($query) use ($booking) {
$duration = ServiceDuration::find($booking['duration']);
$buffer_before = $duration->duration + 31;
$buffer = $duration->duration + 30;
// $buffer = $duration->duration+0;
$buffer_as_time_before = floor($buffer_before / 60) . ':' . ($buffer_before % 60) . ':00';
$buffer_as_time = floor($buffer / 60) . ':' . ($buffer % 60) . ':00';
$query->where('date', date('Y-m-d'))
->whereRaw('`hour` between SUBTIME("' . date('H:i:0') . '","' . $buffer_as_time_before . '") and ADDTIME("' . date('H:i:0') . '","' . $buffer_as_time . '")');
});
return $query;
});
return $query;
})
->orderBy('nr_crt')
->get()
->filter(function ($user) {
return $user->is_subscribed == true;
})
->values();
// return $users;
// $users = User::OfTherapists()->orderBy('nr_crt')
// ->get();
//delete unavailable selected users
if (isset($booking['selected_therapists'])) {
$usersAvailable = [];
foreach ($users as $usr)
$usersAvailable[] = $usr->id;
foreach ($booking['selected_therapists'] as $key => $selected) {
if (!in_array($selected, $usersAvailable))
unset($booking['selected_therapists'][$key]);
} //ennforeach
Session::put('booking', $booking);
} //endif
//calculate first available hour
foreach ($users as $user) {
$user->firstAvHour = $this->getFirstHour($user, $booking);
} //endforeach
$checkduration = ServiceDuration::find($booking['duration'])->duration;
foreach ($users as $key => $u) {
$userSchedule = $u->workingdays()->where('weekday', $weekday)->get()->first();
if (!$u->firstAvHour)
$users->forget($key);
// if (strtotime($whours->bo_end) < strtotime($u->firstAvHour))
// $users->forget($key);
if (strtotime($userSchedule->bo_end) < strtotime($u->firstAvHour . "+{$checkduration} minutes"))
$users->forget($key);
} //endforeach
$sorted = $users->sortBy('firstAvHour');
//return results
return $sorted->values()->all();
}
/**
* Get the first available hour for a specific user
* @param $user
* @param $booking
*/
public function getFirstHour($user, $booking)
{
$result = null;
$fromGeo = [
'lat' => $user->geoLocation->lat,
'lng' => $user->geoLocation->lng
];
if (!$fromGeo || !$booking['address'])
return $result;
//compose from coordinates
$from = "{$fromGeo['lat']},{$fromGeo['lng']}";
//compose to coordonates
// $response = \GoogleMaps::load('textsearch')
// ->setParam([
// 'query' => "{$booking['postcode']}, London UK",
// ])->get('results'); // return $this
$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']}";
} //endif
$mode = $user->transport_mode;
$eta = $this->gTimeTravel($from, $to, $mode);
if (!$eta || $eta > 60)
return null;
//add booking buffer for reservation process: equivalent with the availability in the basket
// $eta+=15;
$eta += 7;
$result = Carbon::now()->addMinutes($eta)->format('H:i');
//return result
return $result;
}
/**
* Calculated estimated time arrival using google maps api: directions
* @param $from
* @param $to
* @param string $mode
* @return mixed
*/
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;
}
/**
* Therapist bookings
* @return \Illuminate\Support\Collection
*/
public function therapistsbookings()
{
$booking = Session::get('booking');
$users = collect();
//if one of mandatory fields is missing, return empty array results
$mandatory_fields = ['postcode', 'duration', 'massage', 'date'];
foreach ($mandatory_fields as $field) {
if (!isset($booking[$field]))
return $users;
} //endforeach
//get postcode zone
$postcode = Postcode::where('postcode', $booking['postcode'])->first();
//query therapists
// DB::enableQueryLog();
$users = User::OfTherapists()
->whereHas('servicetypes', function ($query) use ($booking) {
$query->where('users_servicetype.servicetype_id', $booking['massage']);
return $query;
})
->whereHas('zones', function ($query) use ($postcode) {
$query->where('users_area_coverage.zone_id', $postcode->zone_id);
return $query;
})
->whereHas('workingdays', function ($query) use ($booking) {
$weekday = date('w', strtotime($booking['date']));
$query->where('dayoff', 0);
$query->where('weekday', $weekday);
return $query;
})
// ->whereDoesntHave('daysoff', function($query) use ($booking){
// $query->whereRaw("DATE('".$booking["date"]."') between DATE(date_start) and DATE(date_end)");
// return $query;
//// })
// ->whereDoesntHave('daysoff', function ($query) use ($booking) {
// if (!isset($booking['hour']))
// return $query;
//
// $duration = ServiceDuration::find($booking['duration'])->duration;
//
// $dateHour = $booking['date'].' '.$booking['hour'].':00';
// $query->whereRaw('STR_TO_DATE("'.$dateHour.'","%Y-%m-%d %H:%i") between SUBTIME(SUBTIME(date_start,STR_TO_DATE(CONCAT(FLOOR('.$duration.'/60),\':\',MOD('.$duration.',60)),"%h:%i:%s")),"0:15:00") and ADDTIME(ADDTIME(date_end,STR_TO_DATE(CONCAT(FLOOR('.$duration.'/60),\':\',MOD('.$duration.',60)),"%h:%i:%s")),"0:15:00")');
//// $query->whereRaw("STR_TO_DATE('{$dateHour}','%Y-%m-%d %H:%i') between SUBTIME(date_start, STR_TO_DATE(CONCAT(FLOOR({$duration}/60):MOD({$duration},60)),\"%h:%i:%s\"))) and date_end");
//
// return $query;
// })
->whereHas('therapistbookings', function ($query) use ($booking) {
$query->where('date', $booking['date']);
if (isset($booking['hour']))
$query->whereRaw('`hour` between SUBTIME("' . $booking['hour'] . '","00:15:00") and ADDTIME(ADDTIME("' . $booking['hour'] . '",STR_TO_DATE(CONCAT(FLOOR(duration/60),\':\',MOD(duration,60)),"%h:%i:%s")),"0:15:00")');
return $query;
})
->get();
// dd(DB::getQueryLog());
// dd($users);
// dd($booking);
//return results
return $users;
}
/**
* Get selected therapists
* @return \Illuminate\Support\Collection
*/
public function selected_therapists()
{
$booking = Session::get('booking');
$users = collect();
//if one of mandatory fields is missing, return empty array results
$mandatory_fields = ['selected_therapists'];
foreach ($mandatory_fields as $field) {
if (!isset($booking[$field]))
return $users;
} //endforeach
//query therapists
// DB::enableQueryLog();
$users = User::OfTherapists()
->whereIn('id', $booking['selected_therapists'])
->get();
// dd($users);
//return results
return $users;
}
public function therapist_info($thId)
{
$user = User::OfTherapists()
->with('profile', 'workingdays', 'mywork', 'therapistreview')
->where('id', $thId)
->first();
// dd($user);
if ($user) {
$servicesArray = [];
$services = $user->servicetypes()->where('name', '!=', 'optional')->get();
if ($services) {
foreach ($services as $service) {
$servicesArray[] = $service->name;
}
}
$therapist['data'] = $user;
$therapist['services'] = $servicesArray;
return $therapist;
} else {
return null;
}
}
public function salon_info($thId)
{
$user = User::OfSalon()
->with('profile', 'workingdays', 'mywork', 'reviews', 'salongallaryall')
->where('id', $thId)
->first();
// dd($user);
if ($user) {
$servicesArray = [];
$services = $user->servicetypes()->where('name', '!=', 'optional')->get();
if ($services) {
foreach ($services as $service) {
$servicesArray[] = $service->name;
}
}
$therapist['data'] = $user;
$therapist['services'] = $servicesArray;
return $therapist;
} else {
return null;
}
}
public function salon_therapist_info($thId)
{
$user = User::OfTherapists()
->with('profile', 'workingdays', 'mywork', 'therapistreview')
->where('id', $thId)
->first();
if ($user) {
$servicesArray = [];
$services = $user->salonservicetypes()->where('name', '!=', 'optional')->get();
if ($services) {
foreach ($services as $service) {
$servicesArray[] = $service->name;
}
}
$therapist['data'] = $user;
$therapist['services'] = $servicesArray;
return $therapist;
} else {
return null;
}
}
/**
* Get focal points
*
* @return array
*/
public function focal_points()
{
$points = [];
$focalPoints = FocalPoint::all();
foreach ($focalPoints as $fp)
$points[$fp->side][$fp->slug] = ['id' => $fp->id, 'name' => $fp->name];
//return focal points array
return $points;
}
/**
* Get next 30 days
* @return array
*/
public function available_30_days()
{
$activeDay = Carbon::now()->format('Y-m-d');
$booking = Session::get('booking');
if (isset($booking['date'])) {
$activeDay = $booking['date'];
}
$activeDayTimeStamp = null;
if ($activeDay) {
$activeDayTimeStamp = Carbon::createFromFormat('Y-m-d', $activeDay)->timestamp;
}
$current_30_days = [];
$startDate = Carbon::now();
$startDateTimeStamp = $startDate->timestamp;
$endDate = Carbon::now()->addDays(30);
Carbon::macro('range', function ($startDate, $endDate) {
return new \DatePeriod($startDate, new \DateInterval('P1D'), $endDate);
});
foreach (Carbon::range($startDate, $endDate) as $date) {
$dateTimeStamp = $date->timestamp;
$current_30_days[$dateTimeStamp] = [
'date' => $date->format('Y-m-d'),
'info' => [
'name-day' => substr(strtoupper($date->format('l')), 0, 3),
'nr-date' => $date->format('d'),
'month-name' => substr($date->format('F'), 0, 3),
],
'is-active' => false,
'is-available' => true,
];
if ($dateTimeStamp == $startDateTimeStamp && !$activeDay) {
$current_30_days[$dateTimeStamp]['is-active'] = true;
} elseif ($activeDay && ($dateTimeStamp == $activeDayTimeStamp)) {
$current_30_days[$dateTimeStamp]['is-active'] = true;
}
}
// dd($current_30_days);
return $current_30_days;
}
public function salon_available_30_days()
{
$activeDay = Carbon::now()->format('Y-m-d');
$booking = Session::get('booking');
if (isset($booking['date'])) {
$activeDay = $booking['date'];
}
$activeDayTimeStamp = null;
if ($activeDay) {
$activeDayTimeStamp = Carbon::createFromFormat('Y-m-d', $activeDay)->timestamp;
}
$current_30_days = [];
$startDate = Carbon::now();
$startDateTimeStamp = $startDate->timestamp;
$endDate = Carbon::now()->addDays(30);
Carbon::macro('range', function ($startDate, $endDate) {
return new \DatePeriod($startDate, new \DateInterval('P1D'), $endDate);
});
foreach (Carbon::range($startDate, $endDate) as $date) {
$dateTimeStamp = $date->timestamp;
$current_30_days[$dateTimeStamp] = [
'date' => $date->format('Y-m-d'),
'info' => [
'name-day' => substr(strtoupper($date->format('l')), 0, 3),
'nr-date' => $date->format('d'),
'month-name' => substr($date->format('F'), 0, 3),
],
'is-active' => false,
'is-available' => true,
];
if ($dateTimeStamp == $startDateTimeStamp && !$activeDay) {
$current_30_days[$dateTimeStamp]['is-active'] = true;
} elseif ($activeDay && ($dateTimeStamp == $activeDayTimeStamp)) {
$current_30_days[$dateTimeStamp]['is-active'] = true;
}
}
return $current_30_days;
}
/**
* Get operation hours
*
* @param $date
* @param null $therapist
* @return array|\Illuminate\Support\Collection
*/
public function all_hours($date, $therapist = null)
{
$booking = Session::get('booking');
$bookingPrice = 0;
if (!isset($booking['duration']) && $this->defaultServiceDuration) {
Session::set('booking.duration', $this->defaultServiceDuration->id);
$bookingDuration = $this->defaultServiceDuration;
$bookingPrice = $bookingDuration->price;
} else {
$bookingDuration = ServiceDuration::find($booking['duration']);
$bookingPrice = $bookingDuration->price;
}
//hours collection
$hours = [];
//get today
$today = Carbon::today();
$today_now = Carbon::now();
//cast current date into Carbon object
$dateC = Carbon::createFromFormat('Y-m-d', $date)->startOfDay();
$diff = $today->diffInHours($dateC, false);
if ($diff < 0)
return $hours;
//the buffer between bookings
$buffer = 30;
//if selected date is marked as day off, return empty hours array
$daysOff = $this->days_off($date);
if ($daysOff->count())
return $hours;
//get weekday working hours: if weekday is non working day, return
$weekday = date('w', strtotime($dateC->format('Y-m-d')));
$whours = Schedule::where('weekday', $weekday)->where('open', 1)->first();
if (!$whours)
return $hours;
//data curenta este aceeasi cu cea selectata si ultima ora este mai mica decat ora curenta, nmu mai pot alege o ora din ziua dea zi
if ((date('Y-m-d') == date('Y-m-d', strtotime($date))) && (strtotime($whours->bo_end) < strtotime(date('H:i'))))
return $hours;
//create working hours interval collection
$start = strtotime($whours->bo_start);
$end = strtotime($whours->bo_end);
//pentru data curenta, daca este trecut de ora 23, nu mai poate alege nicio ora.
if (date('Y-m-d') == date('Y-m-d', strtotime($date))) {
$h = date('H');
$i = date('i');
if ($h == 23 and $i > 10)
return $hours;
} //endif
$key = date('H:i', $start);
$hours[$key] = [
'available' => 1,
'hour' => date('H:i', $start),
'price' => $bookingPrice
];
//add remaining hours
while ($start !== $end) {
$start = strtotime('+30 minutes', $start);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 1,
'hour' => date('H:i', $start),
'price' => $bookingPrice
];
} //endwhile
$results = $hours;
//available hours based on current duration selection and therapist schedule
// if(isset($booking['duration'])){
// $unvhours=[];
// $duration = ServiceDuration::find($booking['duration'])->duration;
// $collection = collect($results);
// $unavailable = $collection->filter(function ($value, $key) {
// return $value['available'] == 0;
// });
//
// $unavailable->all();
// foreach($unavailable as $key=>$value){
// $start_hour = Carbon::createFromFormat('H:i',$key)->subMinutes($duration+$buffer);
// $start = strtotime($start_hour->format('H:i'));
//
// //the starting hour cannot be lower than 8:00am
// if ($start < strtotime("08:00"))
// $start = strtotime("08:00");
//
// //set max hour
// $end = strtotime($key);
//
// $unvhours[date('H:i',$start)] = [
// 'available'=>1,
// 'hour'=>date('H:i', $start)
// ];
// while ($start !== $end)
// {
// $start = strtotime('+30 minutes',$start);
// $key = date('H:i', $start);
// $unvhours[$key] = [
// 'available'=>1,
// 'hour'=>date('H:i', $start)
// ];
// } //endwhile
//
// } //endforeach
//
// $results = array_merge($results,$unvhours);
//
// } //endif
// dd($results);
// asort($results);
//available hours for today based on current time
if ($today->format('Y-m-d') == $dateC->format('Y-m-d')) {
//create disabled hours array for today
$inow = Carbon::now()->format('i');
if ($inow >= 30)
$next_time = 60 - Carbon::now()->format('i') + 60;
else
$next_time = 60 - Carbon::now()->format('i') + 30;
$first_av_hour = Carbon::now()->addMinutes($next_time)->format('H:i');
foreach ($results as $hour => $values) {
if (strtotime($hour) < strtotime($first_av_hour)) {
$results[$hour]['available'] = 0;
//if hour is set on unavailable time, reset it with the first available hour
if (isset($booking['hour']) && $booking['hour'] == $hour) {
$booking['hour'] = $first_av_hour;
Session::put('booking', $booking);
}
} //endif
} //ensdforeach
} //endif
//if (selected hour is not available, deselect it and save the new session value)
if (isset($booking['hour']) && @$results[$booking['hour']]['available'] == 0) {
$booking['hour'] = null;
unset($booking['hour']);
Session::put('booking', $booking);
} //endif
//return hours
return collect($results);
}
/**
* Get operation hours
*
* @param $date
* @param null $therapist
* @return array|\Illuminate\Support\Collection
*/
public function all_salon_hours($date, $duration_id = null, $therapist = null)
{
$booking = Session::get('booking');
$bookingPrice = 0;
if ($duration_id == null && !isset($booking['duration']) && $this->defaultServiceDuration) {
Session::set('booking.duration', $this->defaultServiceDuration->id);
$bookingDuration = $this->defaultServiceDuration;
$bookingPrice = $bookingDuration->price;
} else {
// dd($duration_id);
$bookingDuration = SalonServiceDuration::find($duration_id);
$bookingPrice = $bookingDuration->discounted_price;
}
//hours collection
$hours = [];
//get today
$today = Carbon::today();
$today_now = Carbon::now();
//cast current date into Carbon object
$dateC = Carbon::createFromFormat('Y-m-d', $date)->startOfDay();
$diff = $today->diffInHours($dateC, false);
if ($diff < 0)
return $hours;
//the buffer between bookings
$buffer = 10;
//if selected date is marked as day off, return empty hours array
$daysOff = $this->days_off($date);
if ($daysOff->count())
return $hours;
//get weekday working hours: if weekday is non working day, return
$weekday = date('w', strtotime($dateC->format('Y-m-d')));
$whours = Schedule::where('weekday', $weekday)->first();
// dd("here 1", $whours);
if (!$whours)
return $hours;
//data curenta este aceeasi cu cea selectata si ultima ora este mai mica decat ora curenta, nmu mai pot alege o ora din ziua dea zi
if ((date('Y-m-d') == date('Y-m-d', strtotime($date))) && (strtotime($whours->bo_end) < strtotime(date('H:i'))))
return $hours;
//create working hours interval collection
$start = strtotime($whours->bo_start);
$end = strtotime($whours->bo_end);
//pentru data curenta, daca este trecut de ora 23, nu mai poate alege nicio ora.
if (date('Y-m-d') == date('Y-m-d', strtotime($date))) {
$h = date('H');
$i = date('i');
if ($h == 23 and $i > 10)
return $hours;
} //endif
$key = date('H:i', $start);
$hours[$key] = [
'available' => 1,
'hour' => date('H:i', $start),
'price' => $bookingPrice
];
//add remaining hours
while ($start !== $end) {
$start = strtotime('+10 minutes', $start);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 1,
'hour' => date('H:i', $start),
'price' => $bookingPrice
];
} //endwhile
$results = $hours;
//available hours based on current duration selection and therapist schedule
// if(isset($booking['duration'])){
// $unvhours=[];
// $duration = ServiceDuration::find($booking['duration'])->duration;
// $collection = collect($results);
// $unavailable = $collection->filter(function ($value, $key) {
// return $value['available'] == 0;
// });
//
// $unavailable->all();
// foreach($unavailable as $key=>$value){
// $start_hour = Carbon::createFromFormat('H:i',$key)->subMinutes($duration+$buffer);
// $start = strtotime($start_hour->format('H:i'));
//
// //the starting hour cannot be lower than 8:00am
// if ($start < strtotime("08:00"))
// $start = strtotime("08:00");
//
// //set max hour
// $end = strtotime($key);
//
// $unvhours[date('H:i',$start)] = [
// 'available'=>1,
// 'hour'=>date('H:i', $start)
// ];
// while ($start !== $end)
// {
// $start = strtotime('+30 minutes',$start);
// $key = date('H:i', $start);
// $unvhours[$key] = [
// 'available'=>1,
// 'hour'=>date('H:i', $start)
// ];
// } //endwhile
//
// } //endforeach
//
// $results = array_merge($results,$unvhours);
//
// } //endif
// dd($results);
// asort($results);
//available hours for today based on current time
if ($today->format('Y-m-d') == $dateC->format('Y-m-d')) {
//create disabled hours array for today
$inow = Carbon::now()->format('i');
if ($inow >= 30)
$next_time = 60 - Carbon::now()->format('i') + 60;
else
$next_time = 60 - Carbon::now()->format('i') + 30;
$first_av_hour = Carbon::now()->addMinutes($next_time)->format('H:i');
foreach ($results as $hour => $values) {
if (strtotime($hour) < strtotime($first_av_hour)) {
$results[$hour]['available'] = 0;
//if hour is set on unavailable time, reset it with the first available hour
if (isset($booking['hour']) && $booking['hour'] == $hour) {
$booking['hour'] = $first_av_hour;
Session::put('booking', $booking);
}
} //endif
} //ensdforeach
} //endif
//if (selected hour is not available, deselect it and save the new session value)
if (isset($booking['hour']) && @$results[$booking['hour']]['available'] == 0) {
$booking['hour'] = null;
unset($booking['hour']);
Session::put('booking', $booking);
} //endif
//return hours
return collect($results);
}
/**
* Process th hours
*
* @param $starth
* @param $endh
* @param array $excepts
* @return array
*/
protected function process_th_hours($starth, $endh, $excepts = [], $th, $date)
{
$booking = Session::get('booking');
$bookingPrice = 0;
if (!isset($booking['duration']) && $this->defaultServiceDuration) {
Session::set('booking.duration', $this->defaultServiceDuration->id);
$bookingDuration = $this->defaultServiceDuration;
$bookingPrice = $bookingDuration->price;
} else {
// $bookingDuration1 = ServiceDuration::find($booking['duration']);
$bookingDuration = UserServiceDuration::where('services_duration_id', $booking['duration'])
->where('user_id', $th->id)
->first();
if (!$bookingDuration) {
$bookingDuration = ServiceDuration::find($booking['duration']);
}
$bookingPrice = $bookingDuration->price;
}
$hours = [];
$start = strtotime($starth);
$end = strtotime($endh);
$currentHourStart = date('H', $start);
$currentMinuteStart = date('i', $start);
if ($currentMinuteStart > 0 && $currentMinuteStart < 30) {
$start = strtotime('+' . (30 - $currentMinuteStart) . ' minutes', $start);
} elseif ($currentMinuteStart > 30) {
$start = strtotime('+1 hour', $start);
}
//first hour
$key = date('H:i', $start);
$hours[$key] = [
'available' => 1,
'hour' => date('H:i', $start),
'price' => $bookingPrice,
'is_booking' => $th->isBookingHour($date, $key)
];
//add remaining hours
while ($start !== $end) {
$start = strtotime('+30 minutes', $start);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 1,
'hour' => date('H:i', $start),
'price' => $bookingPrice,
'is_booking' => $th->isBookingHour($date, $key)
];
}
//remove hours
if (!empty($excepts)) {
foreach ($excepts as $ex) {
$hours[$ex]['available'] = 0;
$hours[$ex]['price'] = $bookingPrice;
$hours[$ex]['is_booking'] = $th->isBookingHour($date, $ex);
}
}
//return hours
return $hours;
}
/**
* Get operation hours
*
* @param $date
* @param null $therapist
* @return array|\Illuminate\Support\Collection
*/
public function th_hours($date, $therapistId)
{
$booking = Session::get('booking');
$bookingPrice = 0;
if (!isset($booking['duration']) && $this->defaultServiceDuration) {
Session::set('booking.duration', $this->defaultServiceDuration->id);
$bookingDuration = $this->defaultServiceDuration;
$bookingPrice = $bookingDuration->price;
} else {
$bookingDuration = UserServiceDuration::where('services_duration_id', $booking['duration'])
->where('user_id', $therapistId)
->first();
// dd($bookingDuration);
if (!$bookingDuration) {
$bookingDuration = ServiceDuration::find($booking['duration']);
}
$bookingPrice = $bookingDuration->price;
}
//hours collection
$hours = [];
//get today
$today = Carbon::today();
//cast current date into Carbon object
$dateC = Carbon::createFromFormat('Y-m-d', $date)->startOfDay();
$diff = $today->diffInHours($dateC, false);
if ($diff < 0)
return $hours;
//the buffer between bookings
$buffer = 30;
//if selected date is marked as day off, return empty hours array
$daysOff = $this->days_off($date);
if ($daysOff->count())
return $hours;
//get weekday working hours: if weekday is non working day, return
$weekday = date('w', strtotime($dateC->format('Y-m-d')));
$whours = Schedule::where('weekday', $weekday)->where('open', 1)->first();
if (!$whours)
return $hours;
//create working hours interval collection
$start = strtotime($whours->bo_start);
$end = strtotime($whours->bo_end);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 0,
'hour' => date('H:i', $start),
'price' => $bookingPrice,
'is_booking' => false
];
//add remaining hours
while ($start !== $end) {
$start = strtotime('+30 minutes', $start);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 0,
'hour' => date('H:i', $start),
'price' => $bookingPrice,
'is_booking' => false
];
} //endwhile
$therapist = User::where('id', $therapistId)->first();
$th_hours = [];
// $twd = $therapist->workingdays()->where('dayoff',0)->where('weekday',$weekday)->first();
$twds = $therapist->workingdays()->where('dayoff', 0)->where('weekday', $weekday)->get();
// dd("ted",$twds);
if (count($twds) > 0) {
// $c = 0;
foreach ($twds as $key => $twd) {
$blockedHours = $therapist->blockedHours($date);
// print_r($blockedHours);
if (count($blockedHours)) {
foreach ($this->process_th_hours($twd->bo_start, $twd->bo_end, $blockedHours, $therapist, $date) as $key => $value) {
// echo $c++;
if (isset($th_hours[$key]) && $th_hours[$key]['available'] == 0)
continue;
else
$th_hours[$key] = $value;
} //endforeach
} else {
foreach ($this->process_th_hours($twd->bo_start, $twd->bo_end, null, $therapist, $date) as $key => $value) {
// echo $c++;
if (isset($th_hours[$key]) && $th_hours[$key]['available'] == 0)
continue;
else
$th_hours[$key] = $value;
} //endforeach
}
}
} //endif
$results = array_merge($hours, $th_hours);
// dd($results);
//available hours based on current duration selection and therapist schedule
if (isset($booking['duration'])) {
$unvhours = [];
$duration = ServiceDuration::find($booking['duration'])->duration;
$collection = collect($results);
$unavailable = $collection->filter(function ($value, $key) {
return $value['available'] == 0;
});
$unavailable->all();
//dd($unavailable, $results);
foreach ($results as $key => $result) {
if ($result['is_booking']) {
$addedMinutes = $duration + $buffer;
$subMinutes = $duration + $buffer;
} else {
$addedMinutes = $duration;
$subMinutes = 0;
}
$start_hour_after = Carbon::createFromFormat('H:i', $key)->addMinutes($addedMinutes);
$start_after = $start_hour_after->format('H:i');
$start_hour_before = Carbon::createFromFormat('H:i', $key)->subMinutes($subMinutes);
$start_before = $start_hour_before->format('H:i');
$end = strtotime($key);
$start = strtotime($start_before);
if ($result['is_booking']) {
//dd($start_before, $key);
}
//add remaining hours
/*while ($start <= $end)
{
$key = date('H:i', $start);
if(isset($results[$key]))
{
$results[$key]['available'] = 0;
}
$start = strtotime('+30 minutes',strtotime($key));
}*/ //endwhile
$ukeys = [];
if ($subMinutes > 0) {
for ($i = $start; $i <= $end; $i = strtotime('+30 minutes', $i)) {
$ukey = date('H:i', $i);
if (isset($results[$ukey])) {
$results[$ukey]['available'] = 0;
}
$ukeys[] = $ukey;
}
//dd($ukeys);
}
foreach ($unavailable as $k => $item) {
if (strtotime($start_after) > strtotime($k)) {
$results[$key]['available'] = 0;
$unavailable->pull($k);
break;
}
}
}
} //endif
//available hours for today based on current time
if ($today->format('Y-m-d') == $dateC->format('Y-m-d')) {
//create disabled hours array for today
$next_time = 60 - Carbon::now()->format('i') + 30;
$first_av_hour = Carbon::now()->addMinutes($next_time)->format('H:i');
foreach ($results as $hour => $values) {
if (strtotime($hour) < strtotime($first_av_hour)) {
$results[$hour]['available'] = 0;
//if hour is set on unavailable time, reset it with the first available hour
if (isset($booking['hour']) && $booking['hour'] == $hour) {
$booking['hour'] = $first_av_hour;
Session::put('booking', $booking);
}
} //endif
} //ensdforeach
} //endif
//if (selected hour is not available, deselect it and save the new session value)
if (isset($booking['hour']) && @$results[$booking['hour']]['available'] == 0) {
$booking['hour'] = null;
unset($booking['hour']);
Session::put('booking', $booking);
} //endif
//return hours
return collect($results);
}
/**
* Get operation hours
*
* @param $date
* @param null $therapist
* @return array|\Illuminate\Support\Collection
*/
public function hours($date, $therapist = null)
{
$booking = Session::get('booking');
$bookingPrice = 0;
if (!isset($booking['duration']) && $this->defaultServiceDuration) {
Session::set('booking.duration', $this->defaultServiceDuration->id);
$bookingDuration = $this->defaultServiceDuration;
$bookingPrice = $bookingDuration->price;
} else {
$bookingDuration = ServiceDuration::find($booking['duration']);
$bookingPrice = $bookingDuration->price;
}
//hours collection
$hours = [];
//get today
$today = Carbon::today();
//cast current date into Carbon object
$dateC = Carbon::createFromFormat('Y-m-d', $date)->startOfDay();
$diff = $today->diffInHours($dateC, false);
if ($diff < 0)
return $hours;
//the buffer between bookings
$buffer = 30;
//if selected date is marked as day off, return empty hours array
$daysOff = $this->days_off($date);
if ($daysOff->count())
return $hours;
//get weekday working hours: if weekday is non working day, return
$weekday = date('w', strtotime($dateC->format('Y-m-d')));
$whours = Schedule::where('weekday', $weekday)->where('open', 1)->first();
if (!$whours)
return $hours;
//create working hours interval collection
$start = strtotime($whours->bo_start);
$end = strtotime($whours->bo_end);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 0,
'hour' => date('H:i', $start),
'price' => $bookingPrice
];
//add remaining hours
while ($start !== $end) {
$start = strtotime('+30 minutes', $start);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 0,
'hour' => date('H:i', $start),
'price' => $bookingPrice
];
} //endwhile
//available hours based on therapist schedule
if ($therapist != null) {
//therapist from the booking or any other specific request
$therapists = User::whereIn('id', $therapist)->get();
} else {
//available therapists besed on user selection
$therapists = $this->therapists();
}
$th_hours = [];
//select hours only for selected therapists
if (isset($booking['selected_therapists']) && !empty($booking['selected_therapists'])) {
$filtered = $therapists->filter(function ($user, $key) use ($booking) {
return in_array($user->id, $booking['selected_therapists']);
});
$therapists = $filtered;
}
foreach ($therapists as $therapist) {
$twd = $therapist->workingdays()->where('dayoff', 0)->where('weekday', $weekday)->first();
if ($twd) {
$blockedHours = $therapist->blockedHours($date);
if (count($blockedHours)) {
//dd($blockedHours);
foreach ($this->process_hours($twd->bo_start, $twd->bo_end, $blockedHours) as $key => $value) {
if (isset($th_hours[$key]) && $th_hours[$key]['available'] == 0)
continue;
else
$th_hours[$key] = $value;
} //endforeach
} else {
foreach ($this->process_hours($twd->bo_start, $twd->bo_end) as $key => $value) {
if (isset($th_hours[$key]) && $th_hours[$key]['available'] == 0)
continue;
else
$th_hours[$key] = $value;
} //endforeach
// $th_hours = array_merge($th_hours,$this->process_hours($twd->bo_start,$twd->bo_end));
}
} //endif
} //endforeach
//dd($hours, $th_hours);
$results = array_merge($hours, $th_hours);
//available hours based on current duration selection and therapist schedule
if (isset($booking['duration'])) {
$unvhours = [];
$duration = ServiceDuration::find($booking['duration'])->duration;
$collection = collect($results);
$unavailable = $collection->filter(function ($value, $key) {
return $value['available'] == 0;
});
$unavailable->all();
foreach ($unavailable as $key => $value) {
$start_hour = Carbon::createFromFormat('H:i', $key)->subMinutes($duration + $buffer);
//$start_hour = Carbon::createFromFormat('H:i',$key);
$start = strtotime($start_hour->format('H:i'));
//the starting hour cannot be lower than 8:00am
if ($start < strtotime("08:00"))
$start = strtotime("08:00");
//set max hour
$end = strtotime($key);
$unvhours[date('H:i', $start)] = [
'available' => 0,
'hour' => date('H:i', $start),
'price' => $bookingPrice
];
while ($start !== $end) {
$start = strtotime('+30 minutes', $start);
$key = date('H:i', $start);
$unvhours[$key] = [
'available' => 0,
'hour' => date('H:i', $start),
'price' => $bookingPrice
];
} //endwhile
} //endforeach
//dd($results,$unvhours);
$results = array_merge($results, $unvhours);
} //endif
// asort($results);
//available hours for today based on current time
if ($today->format('Y-m-d') == $dateC->format('Y-m-d')) {
//create disabled hours array for today
$next_time = 60 - Carbon::now()->format('i') + 30;
$first_av_hour = Carbon::now()->addMinutes($next_time)->format('H:i');
foreach ($results as $hour => $values) {
if (strtotime($hour) < strtotime($first_av_hour)) {
$results[$hour]['available'] = 0;
//if hour is set on unavailable time, reset it with the first available hour
if (isset($booking['hour']) && $booking['hour'] == $hour) {
$booking['hour'] = $first_av_hour;
Session::put('booking', $booking);
}
} //endif
} //ensdforeach
} //endif
//if (selected hour is not available, deselect it and save the new session value)
if (isset($booking['hour']) && @$results[$booking['hour']]['available'] == 0) {
$booking['hour'] = null;
unset($booking['hour']);
Session::put('booking', $booking);
} //endif
//return hours
return collect($results);
}
/**
* Get operation hours
*
* @param $date
* @return array
*/
public function hours_without_buffer($date, $therapist = null)
{
$booking = Session::get('booking');
//hours collection
$hours = [];
//get today
$today = Carbon::today();
//cast current date into Carbon object
$dateC = Carbon::createFromFormat('Y-m-d', $date)->startOfDay();
$diff = $today->diffInHours($dateC, false);
if ($diff < 0)
return $hours;
//if selected date is marked as day off, return empty hours array
$daysOff = $this->days_off($date);
if ($daysOff->count())
return $hours;
//get weekday working hours: if weekday is non working day, return
$weekday = date('w', strtotime($dateC->format('Y-m-d')));
$whours = Schedule::where('weekday', $weekday)->where('open', 1)->first();
if (!$whours)
return $hours;
//create working hours interval collection
$start = strtotime($whours->bo_start);
$end = strtotime($whours->bo_end);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 0,
'hour' => date('H:i', $start)
];
//add remaining hours
while ($start !== $end) {
$start = strtotime('+30 minutes', $start);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 0,
'hour' => date('H:i', $start)
];
} //endwhile
//available hours based on therapist schedule
if ($therapist != null) {
//therapist from the booking or any other specific request
$therapists = User::whereIn('id', $therapist)->get();
} else {
//available therapists besed on user selection
$therapists = $this->therapists();
}
$th_hours = [];
//select hours only for selected therapists
if (isset($booking['selected_therapists'])) {
$filtered = $therapists->filter(function ($user, $key) use ($booking) {
return in_array($user->id, $booking['selected_therapists']);
});
$therapists = $filtered;
}
foreach ($therapists as $therapist) {
$twd = $therapist->workingdays()->where('dayoff', 0)->where('weekday', $weekday)->first();
if ($twd) {
$blockedHours = $therapist->blockedHours($date);
if (count($blockedHours)) {
foreach ($this->process_hours($twd->bo_start, $twd->bo_end, $blockedHours) as $key => $value) {
if (isset($th_hours[$key]) && $th_hours[$key]['available'] == 0)
continue;
else
$th_hours[$key] = $value;
} //endforeach
// $th_hours = array_merge($th_hours,$this->process_hours($twd->bo_start,$twd->bo_end,$blockedHours));
} else {
foreach ($this->process_hours($twd->bo_start, $twd->bo_end) as $key => $value) {
if (isset($th_hours[$key]) && $th_hours[$key]['available'] == 0)
continue;
else
$th_hours[$key] = $value;
} //endforeach
// $th_hours = array_merge($th_hours,$this->process_hours($twd->bo_start,$twd->bo_end));
}
} //endif
} //endforeach
$results = array_merge($hours, $th_hours);
//available hours based on current duration selection and therapist schedule
if (isset($booking['duration'])) {
$unvhours = [];
$duration = ServiceDuration::find($booking['duration'])->duration;
$collection = collect($results);
$unavailable = $collection->filter(function ($value, $key) {
return $value['available'] == 0;
});
$unavailable->all();
foreach ($unavailable as $key => $value) {
$start_hour = Carbon::createFromFormat('H:i', $key)->subMinutes($duration);
$start = strtotime($start_hour->format('H:i'));
$end = strtotime($key);
$unvhours[date('H:i', $start)] = [
'available' => 0,
'hour' => date('H:i', $start)
];
// while ($start !== $end)
// {
// $start = strtotime('+30 minutes',$start);
// $key = date('H:i', $start);
// $unvhours[$key] = [
// 'available'=>0,
// 'hour'=>date('H:i', $start)
// ];
// } //endwhile
} //endforeach
$results = array_merge($results, $unvhours);
} //endif
// dd($results);
// asort($results);
//available hours for today based on current time
if ($today->format('Y-m-d') == $dateC->format('Y-m-d')) {
//create disabled hours array for today
$next_time = 60 - Carbon::now()->format('i') + 30;
$first_av_hour = Carbon::now()->addMinutes($next_time)->format('H:i');
foreach ($results as $hour => $values) {
if (strtotime($hour) < strtotime($first_av_hour)) {
$results[$hour]['available'] = 0;
//if hour is set on unavailable time, reset it with the first available hour
if (isset($booking['hour']) && $booking['hour'] == $hour) {
$booking['hour'] = $first_av_hour;
Session::put('booking', $booking);
}
} //endif
} //ensdforeach
} //endif
//if (selected hour is not available, deselect it and save the new session value)
if (isset($booking['hour']) && @$results[$booking['hour']]['available'] == 0) {
$booking['hour'] = null;
unset($booking['hour']);
Session::put('booking', $booking);
} //endif
//return hours
return collect($results);
}
/**
* Process hours
*
* @param $starth
* @param $endh
* @param array $excepts
* @return array
*/
protected function process_hours($starth, $endh, $excepts = [])
{
$booking = Session::get('booking');
$bookingPrice = 0;
if (!isset($booking['duration']) && $this->defaultServiceDuration) {
Session::set('booking.duration', $this->defaultServiceDuration->id);
$bookingDuration = $this->defaultServiceDuration;
$bookingPrice = $bookingDuration->price;
} else {
$bookingDuration = ServiceDuration::find($booking['duration']);
$bookingPrice = $bookingDuration->price;
}
$hours = [];
$start = strtotime($starth);
$end = strtotime($endh);
$currentHourStart = date('H', $start);
$currentMinuteStart = date('i', $start);
if ($currentMinuteStart > 0 && $currentMinuteStart < 30) {
$start = strtotime('+' . (30 - $currentMinuteStart) . ' minutes', $start);
} elseif ($currentMinuteStart > 30) {
$start = strtotime('+1 hour', $start);
}
//first hour
$key = date('H:i', $start);
$hours[$key] = [
'available' => 1,
'hour' => date('H:i', $start),
'price' => $bookingPrice,
];
//add remaining hours
while ($start !== $end) {
$start = strtotime('+30 minutes', $start);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 1,
'hour' => date('H:i', $start),
'price' => $bookingPrice
];
}
//remove hours
if (!empty($excepts)) {
foreach ($excepts as $ex) {
$hours[$ex]['available'] = 0;
$hours[$ex]['price'] = $bookingPrice;
// unset($hours[$ex]);
}
}
//return hours
return $hours;
}
/**
* Check if a date is a non-working day
*/
public function days_off($start_date = null)
{
//set date
if (!$start_date)
$start_date = date('Y-m-d 00:00:00');
else
$start_date = Carbon::createFromFormat('Y-m-d', $start_date)->format('Y-m-d H:i:s');
//query selected date between non working days
$nwdays = ScheduleDaysOff::whereRaw("'" . $start_date . "' between date_start and date_end")->get();
//return results: non working days
return $nwdays;
}
public function getAndSetFirstAvailableDayHour()
{
$booking = Session::get('booking');
if (!isset($booking['date'])) {
$date = date('Y-m-d');
} else {
$date = $booking['date'];
}
$hours = $this->all_hours($date);
$firstHour = null;
if ($hours) {
foreach ($hours as $hour) {
if ($hour['available']) {
$firstHour = $hour;
break;
}
}
if ($firstHour) {
Session::set('booking.hour', $firstHour['hour']);
return $firstHour;
}
}
}
public function getAndSetFirstAvailableDayHourSalon()
{
$booking = Session::get('booking');
$cartItem = Session::get('cartItem');
if (!isset($booking['date'])) {
$date = date('Y-m-d');
} else {
$date = $booking['date'];
}
$hours = $this->all_salon_hours($date, $cartItem->duration_id);
$firstHour = null;
if ($hours) {
foreach ($hours as $hour) {
if ($hour['available']) {
$firstHour = $hour;
break;
}
}
if ($firstHour) {
Session::set('booking.hour', $firstHour['hour']);
return $firstHour;
}
}
}
/**
* Get available days
*
* @return array
*/
public function days()
{
$days = [];
//todo
//return dates
return $days;
}
/**
* Get Order Details by Card transaction id
* @param $card_trans_id
*/
public function get_order_cart($card_trans_id)
{
return BookingOrder::where('card_trans_id', $card_trans_id)->get();
}
/**
* Return if the booking can be cancelled
* @param $id
* @return bool
*/
public function can_be_safe_canceled(BookingOrder $obj)
{
//default response value
$response = false;
//get order info
$orderInfo = json_decode($obj->orderInfo, true);
//if in the order has been used an voucher code, the amount is not refundable
// if ($orderInfo['has_voucher'])
// return $response=false;
$now = Carbon::now();
$dateHourOrder = $obj->date->format('Y-m-d') . ' ' . $obj->hour;
$orderTime = Carbon::createFromFormat('Y-m-d H:i', $dateHourOrder);
//if the cancellation is done by the client in less than 3 hours before the booking, the amount is not refundable
$safe_cancel = $now->diffInMinutes($orderTime, false);
if ($safe_cancel > 90) {
$response = true;
} else {
$response = false;
}
//return response
return $response;
}
/**
* Cancel order and refund value
* @param BookingOrder $obj
*/
public function cancel_order(BookingOrder $obj, $admin = false)
{
//start transaction
DB::beginTransaction();
//first refund the value
$refundStatus = $this->refund_value_of($obj, $admin);
$orderInfo = json_decode($obj->orderInfo, true);
$therapistsIds = $orderInfo['therapistIds'];
//cancel order
$obj->is_active = 0;
$success = $obj->save();
//refund voucher and cvancel invoice only if the booking can be safe canceled
if ($this->can_be_safe_canceled($obj)) {
//refund voucher value
$refundVoucher = $this->refund_voucher_of($obj, $admin);
//refund invoice
$refundInvoice = $this->cancel_invoice_of($obj);
} //end
//add mobile app notifications to the client and therepists
//compose message
$notif_message = trans("schedules::booking.mobile_cancel_order", ['number' => $obj->id, 'date' => $obj->date_to_human, 'hour' => $obj->hour_to_human]);
//notification users array
$notif_users[] = $obj->user_id;
foreach ($therapistsIds as $thid)
$notif_users[] = $thid;
//store notifications
foreach ($notif_users as $user)
NotifRepository::add($user, $notif_message, 'cancelBooking', 'Booking cancelled');
//commit-rollback transaction
if ($success) {
//commit
DB::commit();
//send confirmation email
$user = User::findOrFail($obj->user_id);
$data['user'] = $user;
$data['order'] = $obj;
Mail::send('schedules::frontend.emails.cancelorder', ['user' => $user, 'order' => $obj], function ($m) use ($data) {
$m->from(env('MAIL_FROM'), env('APP_NAME'));
$m->to($data['user']->email, $data['user']->name);
$m->bcc(explode(',', env('MAIL_NEWORDER_BCC')), env('MAIL_NEWORDER_BCC_NAME'));
$m->subject('Tradze – cancel booking #' . $data['order']->id);
});
//send therapist email confirmation
//send confirmation email
$thusers = User::whereIn('id', $notif_users)->get();
foreach ($thusers as $therapist) {
$data['user'] = $therapist;
Mail::send('schedules::frontend.emails.therapist_cancelorder', ['user' => $therapist, 'order' => $obj], function ($m) use ($data) {
$m->from(env('MAIL_FROM'), env('APP_NAME'));
$m->to($data['user']->email, $data['user']->name);
$m->bcc(explode(',', env('MAIL_NEWORDER_BCC')), env('MAIL_NEWORDER_BCC_NAME'));
$m->subject(env('APP_NAME') . ' – cancel booking #' . $data['order']->id);
});
}
} else {
//rollback actions
DB::rollBack();
} //end elseif transaction
//create response array
$response = [
'success' => $success,
'message' => $refundStatus['message'],
];
//return response
return $response;
}
/**
* Refund payments with credit card
* @param BookingOrder $obj
* @return bool
*/
protected function refund_value_of(BookingOrder $obj, $admin = false)
{
$response = [
'success' => false,
'message' => null,
];
if (!$admin) {
$safe_cancel = $this->can_be_safe_canceled($obj);
$response = [
'success' => false,
'message' => null,
];
} else
$safe_cancel = true;
//to refund, all the conditions must be valid
// if (!$safe_cancel || !$obj->card_trans_id || !$obj->card_trans_status || !$obj->amount>0 || !$obj->is_active)
// return $response;
//if the booking was paid by cash
if (!$safe_cancel && empty($obj->card_trans_id) && $obj->amount > 0 && $obj->is_active) {
$response['message'] = $this->charge_from_card($obj);
return $response;
} //end
//The Booking was paid with card and cannot be canceled.
if (!$obj->card_trans_id || !$obj->card_trans_status || !($obj->amount > 0) || !$obj->is_active || !$safe_cancel)
return $response;
// Try to refund the amount
try {
//according with sagepay, refund is available only for yesterday
if ($obj->created_at->format('Y-m-d') != date('Y-m-d'))
$response = $this->opt_refund($obj);
else
$response = $this->opt_void($obj);
// //BRAINTREE first find breintree transaction
// $trans = Transaction::find($obj->card_trans_id);
//
// //then select method based on transaction status
// switch ($trans->status){
// case 'settled':
// case 'settling':
// $response = $this->opt_refund($obj);
// break;
// case 'submitted_for_settlement':
// $response = $this->opt_void($obj);
// break;
// default:
// $response = $this->opt_void($obj);
// break;
// } //endwitch
} catch (\Exception $e) {
//the transaction id not found
$response['message'] = $e->getMessage();
}
//return message
return $response;
}
/**
* Charge money from card
* @param $obj
*/
public function charge_from_card($obj)
{
//todo: for the moment, just return null.
return null;
$user = User::find($obj->user_id);
$message = '';
//check if user exists
if (!$user)
return $message;
//user has no valid card defined
if (!$user->braintree_id) {
$message = strtoupper("You have no valid card defined. Please enter one below!");
return $message;
} //endif
try {
$name = "massage services";
$total = $obj->amount;
$response = $user->invoiceFor($name, $total);
} catch (\Exception $e) {
$message = $e->getMessage();
$message = str_ireplace('braintree', 'Tradze', $message);
return $message;
}
//update transaction type from cash to card
$data = [
'card_trans_id' => $response->transaction->id,
'card_trans_status' => (bool)$response->success,
'card_details' => json_encode([
'customerLocation' => $response->transaction->creditCardDetails->customerLocation,
'cardType' => $response->transaction->creditCardDetails->cardType,
'expirationDate' => $response->transaction->creditCardDetails->expirationDate,
'imageUrl' => $response->transaction->creditCardDetails->imageUrl,
'maskedNumber' => $response->transaction->creditCardDetails->maskedNumber,
'last4' => $response->transaction->creditCardDetails->last4,
'bin' => $response->transaction->creditCardDetails->bin,
]),
];
//update transaction type
$obj->update($data);
}
/**
* Refund voucher value of booking order
* @param BookingOrder $obj
* @param bool $admin
*/
protected function refund_voucher_of(BookingOrder $obj, $admin = false)
{
$response = [
'success' => false,
'message' => null,
];
$info = json_decode($obj->orderInfo, true);
if (!$admin) {
$safe_cancel = $this->can_be_safe_canceled($obj);
$response = [
'success' => false,
'message' => null,
];
} else
$safe_cancel = true;
//to refund voucher value, all conditions must be true
if (!$safe_cancel || !$info['has_voucher'] || !$info['price_net'] || !$info['voucher']['code'])
return $response;
//continue with voucher value refund
$qty = 1;
switch ($info['therapistsOpt']) {
case '4hands':
$qty = 1;
break;
default:
$qty = 1;
break;
} //end switch
$voucherRepo = new VoucherRepository();
$status = $voucherRepo->refund_value($info['voucher']['code'], $info['price_net'], $qty);
//cancel invoice
$response = [
'success' => $status['status'],
'message' => $status['message'],
];
//return response
return $response;
}
/**
* Refund Function
* @param $obj
* @return array
*/
protected function opt_refund($obj)
{
$gateway = Omnipay::create('SagePay\Direct');
$gateway->setVendor(env('SAGEPAY_VENDOR_NAME'));
$gateway->setTestMode(env('SAGEPAY_TEST_MODE'));
$payload = json_decode($obj->card_trans_id, true);
$result = $gateway->refund(array(
'useAuthenticate' => false,
'transactionReference' => $obj->card_trans_id,
'transactionId' => $payload['VendorTxCode'] . '-REF',
'amount' => $obj->amount,
'currency' => env('SAGEPAY_CCY'),
'description' => 'Massage services cancelled',
))->send();
$response = [
'success' => $result->isSuccessful(),
'message' => (!$result->isSuccessful()) ? $result->getMessage() : trans('schedules::booking.text_successfully_refunded'),
];
return $response;
}
/**
* Void Function
* @param $obj
* @return array
*/
protected function opt_void($obj)
{
$gateway = Omnipay::create('SagePay\Direct');
$gateway->setVendor(env('SAGEPAY_VENDOR_NAME'));
$gateway->setTestMode(env('SAGEPAY_TEST_MODE'));
$result = $gateway->void(array(
'useAuthenticate' => false,
'transactionReference' => $obj->card_trans_id,
'amount' => $obj->amount,
'currency' => env('SAGEPAY_CCY'),
'description' => 'Massage services cancelled',
))->send();
$orderInfo = json_decode($obj->orderInfo, true);
//void the extension
if ($orderInfo['has_extension'] && array_key_exists('extension', $orderInfo)) {
$ext_result = $gateway->void(array(
'useAuthenticate' => false,
'transactionReference' => $orderInfo['extension']['card_details']['transaction_reference'],
'amount' => $orderInfo['extension']['price'],
'currency' => env('SAGEPAY_CCY'),
'description' => 'Massage services - extension cancelled',
))->send();
} //end void the extension
$response = [
'success' => $result->isSuccessful(),
'message' => (!$result->isSuccessful()) ? $result->getMessage() : trans('schedules::booking.text_successfully_refunded'),
];
return $response;
}
/**
* Cancel invoice of booking order
*/
public function cancel_invoice_of($obj)
{
$status = false;
$invoice = $obj->invoice;
if (!$invoice)
return $status;
$repoInv = new BookingInvoiceRepository();
$status = $repoInv->cancel_invoice($invoice->id);
return $status;
}
/**
* Set saved booking data into session
* @param $obj
*/
public function set_booking_data($obj)
{
//first unset any booking data
$this->unset_booking_data();
//get info of booking details
$info = json_decode($obj->orderInfo, true);
//set new data
$data = [
'postcode' => $info['postcode'],
'duration' => $info['duration_id'],
'massage' => $info['massage_type_id'],
'date' => $obj->date->format('Y-m-d'),
'hour' => $obj->hour,
'selected_therapists' => $info['therapistIds'],
'therapists_opt' => $info['therapistsOpt'],
'therapists' => $info['therapistsNo'],
'type' => $info['type'],
];
//store new data into session
Session::put('booking', $data);
}
/**
* Set saved booking data into session
* @param $obj
*/
public function unset_booking_data()
{
Session::forget('booking');
}
/**
* User can extends thier booking with another service
*
* @param $booking
* @param $service
* @return bool
*/
public function can_extend_with($booking, $service)
{
//default status
$status = false;
//get booking therapists
$therapists = $booking->therapists;
//add extention time to the current booking + 15min buffer to check if booking will overlaps
$addTime = $booking->duration_min + $service->duration + 58;
$addTime2 = $booking->duration_min + $service->duration;
//calculate diff in minutes between end of massage session and current time
$bookingEndTime = Carbon::createFromFormat('Y-m-d H:i', "{$booking->date->format('Y-m-d')} {$booking->hour}")->addMinutes($booking->duration_min);
$diff = $bookingEndTime->diffInMinutes(Carbon::now(), false);
$bookingEndTime2 = Carbon::createFromFormat('Y-m-d H:i', "{$booking->date->format('Y-m-d')} {$booking->hour}")->addMinutes($addTime2)->format('Y-m-d H:i');
//check if extension ca be made regarding the therapist schedule
$weekday = date('w', strtotime($booking->date));
foreach ($therapists as $th) {
$thWeekDaySchedule = $th->workingdays()->where('weekday', $weekday)->get()->first();
if (!$thWeekDaySchedule)
continue;
$endOfSchedule = Carbon::createFromFormat('Y-m-d H:i A', "{$booking->date->format('Y-m-d')} {$thWeekDaySchedule->bo_end}")->format('Y-m-d H:i');
$diffEndOfSchedule = strtotime($endOfSchedule) - strtotime($bookingEndTime2);
// dd([
// '$thWeekDaySchedule'=>$thWeekDaySchedule,
// '$endOfSchedule'=>$endOfSchedule,
// '$bookingEndTime' => $bookingEndTime2,
// '$diffEndOfSchedule'=>$diffEndOfSchedule,
// ]);
if ($diffEndOfSchedule < 0)
return false;
} //endforeach
//if the current time is bigger than the booking session time, add minutes which passed over session booking end time to the addTime variable.
//this will
if ($diff > 0)
$addTime += $diff;
$timewithbuffer = floor($addTime / 60) . ':' . ($addTime % 60);
$count = 0;
//for each therapist, check if selected service-extension overlap on another booking
foreach ($therapists as $trp) {
// DB::enableQueryLog();
$thBookings = $trp->therapistbookings()
->where('date', '=', $booking->date->format('Y-m-d'))
->whereRaw('hour between SUBTIME("' . $booking->hour . '","00:15") and ADDTIME("' . $booking->hour . '" ,"' . $timewithbuffer . '")')
->where('booking_id', '!=', $booking->id)
->whereHas('booking', function ($query) {
return $query->where('is_active', 1);
})
->get();
// dd(DB::getQueryLog());
$count += $thBookings->count();
//todo: check if other booking is in the session basket
} //endforeach
//if the therapists has bookings, deny extension
if ($count)
return $status;
//if the therapists has no other bookings, let the user to extend his session
$status = true;
//return status
return $status;
}
/**
* Therapist can delay the booking with number of minutes (@param delay)
* @param $booking
* @param int $delay
* @return bool
*/
public function can_delay_with($booking, $delay)
{
//default status
$status = false;
$delay = (int)$delay;
//get booking therapists
$therapists = $booking->therapists;
//add delay time to the current booking + 15min buffer to determine if booking will overlaps
$addTime = $booking->duration_min + $delay + 15;
//calculate diff in minutes between end of massage session and current time
$bookingEndTime = Carbon::createFromFormat('Y-m-d H:i', "{$booking->date->format('Y-m-d')} {$booking->hour}")->addMinutes($booking->duration_min);
$diff = $bookingEndTime->diffInMinutes(Carbon::now(), false);
//if the current time is bigger than the booking session time, add minutes which passed over session booking end time to the addTime variable.
//this will
if ($diff > 0)
$addTime += $diff;
$timewithbuffer = floor($addTime / 60) . ':' . ($addTime % 60);
$count = 0;
//for each therapist, check if selected service-extension overlap on another booking
foreach ($therapists as $trp) {
// DB::enableQueryLog();
$thBookings = $trp->therapistbookings()
->where('date', '=', $booking->date->format('Y-m-d'))
->whereRaw('hour between SUBTIME("' . $booking->hour . '","00:15") and ADDTIME("' . $booking->hour . '" ,"' . $timewithbuffer . '")')
->where('booking_id', '!=', $booking->id)
->whereHas('booking', function ($query) {
return $query->where('is_active', 1);
})
->get();
// dd(DB::getQueryLog());
$count += $thBookings->count();
//todo: check if other booking is in the session basket
} //endforeach
//if the therapists has bookings, deny extension
if ($count)
return $status;
//if the therapists has no other bookings, let the user to extend his session
$status = true;
//return status
return $status;
}
/**
* Start booking threading
* @param $booking
*/
public function create_thread($booking)
{
$subject = $booking->treadsubject;
$thread = Thread::where('subject', $subject)->first();
//create the thread if not exists
if (!$thread) {
$thread = Thread::create(
[
'subject' => $subject,
]
);
} //endif
// create message
Message::create(
[
'thread_id' => $thread->id,
'user_id' => $booking->user_id,
'body' => trans('schedules::booking.default_message_thread'),
]
);
// Add replier as a participant
$participant = Participant::firstOrCreate(
[
'thread_id' => $thread->id,
'user_id' => $booking->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);
} //end method
public function checkPhoneNumber($phone)
{
$phone = trim($phone);
$phone = preg_replace("/[^0-9]/", "", $phone);
$phoneLen = strlen($phone);
$firstDigit = substr($phone, 0, 1);
if ($phoneLen >= 10 && $phoneLen <= 14 && $firstDigit == 0) {
return true;
} else {
return false;
}
}
// Salon therapist
public function salontherapists()
{
$booking = Session::get('booking');
$session = Session::all();
// dd($session['cartItem']->salon_id);
$users = collect();
//if one of mandatory fields is missing, return empty array results
$mandatory_fields = ['date', 'address'];
foreach ($mandatory_fields as $field) {
if (!isset($booking[$field]))
return $users;
} //endforeach
;
//get postcode zone
// $postcode = Postcode::where('postcode', $booking['postcode'])->first();
//users are not available for the past dates
$today = Carbon::today();
$dateC = Carbon::createFromFormat('Y-m-d', $booking['date']);
$diff = $today->diffInHours($dateC, false);
if ($diff < 0)
return $users;
// dd("here 2");
//query therapists
DB::enableQueryLog();
$users = User::with('salonservicetypes', 'profile', 'mywork')->where('salon_id', $session['cartItem']->salon_id)
->whereHas('salonservicetypes', function ($query) use ($booking, $session) {
// dd("here",$session['cartItem']->subcategory_id);
if (isset($session['cartItem']->subcategory_id) && $session['cartItem']->subcategory_id > 0)
$query->where('users_servicetype.servicetype_id', '=', $session['cartItem']->subcategory_id);
return $query;
})
->whereHas('workingdays', function ($query) use ($booking, $session) {
$weekday = date('w', strtotime($booking['date']));
$hour = $booking['hour'] . ':00';
$duration = SalonServiceDuration::find($session['cartItem']->duration_id)->duration;
$hourEnd = Carbon::createFromFormat('H:i:s', $hour)->addMinutes($duration)->format('H:i:s');
if (strtotime($hour) > strtotime($hourEnd))
return $query->where('id', '-1');
$query->where('dayoff', 0);
$query->where('weekday', $weekday);
$query->whereRaw("TIME(STR_TO_DATE(bo_start, '%H:%i')) <= TIME(STR_TO_DATE('{$hour}','%H:%i')) and TIME(STR_TO_DATE(bo_end, '%H:%i')) >= TIME(STR_TO_DATE('{$hourEnd}','%H:%i'))");
return $query;
})
->whereDoesntHave('daysoff', function ($query) use ($booking, $session) {
if (!isset($booking['hour']))
return $query;
$duration = SalonServiceDuration::find($session['cartItem']->duration_id)->duration;
$duration = $duration - 1;
$dateHour = $booking['date'] . ' ' . $booking['hour'] . ':00';
$dateHourEnd = $booking['date'] . ' ' . date('H:i', strtotime($booking['hour'] . "+{$duration} minutes")) . ':00';
$query->whereRaw('STR_TO_DATE("' . $dateHour . '","%Y-%m-%d %H:%i") > date_start and date_end > STR_TO_DATE("' . $dateHour . '","%Y-%m-%d %H:%i")')
->orWhereRaw('STR_TO_DATE("' . $dateHourEnd . '","%Y-%m-%d %H:%i") > date_start and date_end > STR_TO_DATE("' . $dateHourEnd . '","%Y-%m-%d %H:%i")');
//dd($dateHour,$dateHourEnd);
return $query;
})
->orderBy('nr_crt')
->get();
// dd($users);
// return $users;
// dd($session);
//unselect unavailable selected users
if (isset($booking['selected_therapists'])) {
$usersAvailable = [];
foreach ($users as $usr)
$usersAvailable[] = $usr->id;
foreach ($booking['selected_therapists'] as $key => $selected) {
if (!in_array($selected, $usersAvailable))
unset($booking['selected_therapists'][$key]);
}
Session::put('booking', $booking);
}
if (isset($booking['hour']) && isset($session['cartItem'])) {
$duration = SalonServiceDuration::find($session['cartItem']->duration_id);
$bufferMin = 55;
$buffer = $duration->duration + 10;
foreach ($users as $key => $u) {
//remove user is he has already a booking at selected date&hour + duration interval
$count = $u->therapistbookings()
->where('date', $booking['date'])
->where(function ($query) use ($booking, $duration, $buffer, $bufferMin) {
return $query->whereRaw('
TIME("' . $booking['hour'] . '") BETWEEN SUBTIME(`hour`,STR_TO_DATE(CONCAT(FLOOR(' . $buffer . '/60),\':\',MOD(' . $buffer . ',60)),"%h:%i:%s")) AND ADDTIME(`hour`,STR_TO_DATE(CONCAT(FLOOR((duration+' . $bufferMin . ')/60),\':\',MOD((duration+' . $bufferMin . '),60)),"%h:%i:%s"))
');
})
->whereHas('booking', function ($query) {
return $query->where('is_active', 1);
})
->count();
if ($count) $users->forget($key);
$countSession = $u->sessionBlockedTherapists()
->where('date', $booking['date'])
->where(function ($query) use ($booking, $duration, $buffer, $bufferMin) {
return $query->whereRaw('
`hour` between SUBTIME("' . $booking['hour'] . '",STR_TO_DATE(CONCAT(FLOOR(' . $buffer . '/60),\':\',MOD(' . $buffer . ',60)),"%h:%i:%s")) and ADDTIME(ADDTIME("' . $booking['hour'] . '",STR_TO_DATE(CONCAT(FLOOR(' . $buffer . '/60),\':\',MOD(' . $buffer . ',60)),"%h:%i:%s")),"0:00:00")
OR
ADDTIME(`hour`, STR_TO_DATE(CONCAT(FLOOR(duration_min/60),\':\',MOD(duration_min,60)),"%h:%i:%s")) BETWEEN SUBTIME("' . $booking['hour'] . '", "00:55:00") AND ADDTIME(ADDTIME("' . $booking['hour'] . '",STR_TO_DATE(CONCAT(FLOOR(' . $buffer . '/60),\':\',MOD(' . $buffer . ',60)),"%h:%i:%s")),"0:00:00")
');
})
->count();
if ($countSession) $users->forget($key);
} //end foreach
} //endif
$usersAvailable = [];
//unselect unavailable selected users
//if (isset($booking['selected_therapists'])){
foreach ($users as $usr)
$usersAvailable[] = $usr->id;
if (isset($booking['selected_therapists'])) {
foreach ($booking['selected_therapists'] as $key => $selected) {
if (!in_array($selected, $usersAvailable))
unset($booking['selected_therapists'][$key]);
}
}
Session::put('booking', $booking);
//}
// dd($session, $booking);
$usersUnAvailable = User::with('salonservicetypes', 'profile', 'mywork')->where('salon_id', $session['cartItem']->salon_id)
->whereHas('salonservicetypes', function ($query) use ($booking, $session) {
// dd("here",$session['cartItem']->subcategory_id);
if (isset($session['cartItem']->subcategory_id) && $session['cartItem']->subcategory_id > 0)
$query->where('users_servicetype.servicetype_id', '=', $session['cartItem']->subcategory_id);
return $query;
})
->whereNotIn('id', $usersAvailable)
// ->whereHas('servicetypes', function ($query) use ($booking) {
// if (isset($booking['massage']) && $booking['massage'] > 0)
// $query->where('users_servicetype.servicetype_id', $booking['massage']);
// return $query;
// })
// ->whereHas('zones', function ($query) use ($postcode) {
// $query->where('users_area_coverage.zone_id', $postcode->zone_id);
// return $query;
// })
->orderBy('nr_crt')
->get();
// return $usersUnAvailable;
// session Address
// $addr_longitude = '';
// $addr_latitude = '';
// $address = $booking['address'];
// if(!empty($address)){
// //Formatted address
// $formattedAddr = str_replace(' ','+',$address);
// //Send request and receive json data by address
// $geocodeFromAddr = file_get_contents('https://maps.googleapis.com/maps/api/geocode/json?address='.$formattedAddr.'&sensor=false&key='.config("googlemaps.key"));
// $output = json_decode($geocodeFromAddr);
// //Get latitude and longitute from json data
// $addr_longitude = !empty($output->results[0]->geometry->location->lat)?$output->results[0]->geometry->location->lat:'';
// $addr_latitude = !empty($output->results[0]->geometry->location->lng)?$output->results[0]->geometry->location->lng:'';
// }
// check available users in coverage locations
// $available_user_results = array();
// if(!empty($users)){
// foreach($users as $th){
// $is_in_polygon = 0;
// $therapist_coverages_1 = UserCoverageArea::where('user_id',$th->id)->get();
// $therapist_coverages_last = UserCoverageArea::where('user_id',$th->id)->orderBy('id','DESC')->first();
// if(!empty($therapist_coverages_last->polygon_no)){
// foreach($therapist_coverages_1 as $thp_cover){
// //for ($i = 0; $i <= $therapist_coverages_last->polygon_no; $i++) {
// $therapist_coverages = UserCoverageArea::select('lng','lat')->where('user_id',$th->id)->where('polygon_no',$thp_cover->polygon_no)->get();
// $polygon_lat_lng_Arr = array();
// foreach ($therapist_coverages as $coverages) {
// $longitude = $coverages->lng;
// $latitude = $coverages->lat;
// $polygon_lat_lng_Arr[] = $longitude.' '.$latitude;
// }
// $longitude_x = $addr_longitude; // x-coordinate of the point to test
// $latitude_y = $addr_latitude; // y-coordinate of the point to test
// //echo $point = $longitude_x.' '.$latitude_y;
// $point = $latitude_y.' '.$longitude_x;
// //print_r($polygon_lat_lng_Arr);
// if (UserCoverageArea::pointInPolygon($point, $polygon_lat_lng_Arr)){
// $is_in_polygon++;
// }
// //echo $is_in_polygon;
// }
// }
// if(!empty($addr_longitude) && !empty($addr_latitude)){
// if($is_in_polygon > 0){
// $is_in_polygon = 0;
// $user_profile = DB::table("users_profile")->where("user_id", $th->id)->first();
// if($user_profile->massage_me_now){
// $available_user_results[] = $th;
// }
// }
// }
// }
// }
// return $usersUnAvailable;
// check unavailable users in coverage locations
// $unavailable_user_results = array();
// if(!empty($usersUnAvailable)){
// $is_in_polygon = 0;
// foreach($usersUnAvailable as $th){
// $therapist_coverages_1 = UserCoverageArea::where('user_id',$th->id)->get();
// $therapist_coverages_last = UserCoverageArea::where('user_id',$th->id)->orderBy('id','DESC')->first();
// if(!empty($therapist_coverages_last->polygon_no) && !empty($therapist_coverages_1)){
// foreach($therapist_coverages_1 as $thp_cover){
// //for ($i = 0; $i <= $therapist_coverages_last->polygon_no; $i++) {
// $therapist_coverages = UserCoverageArea::select('lng','lat')->where('user_id',$th->id)->where('polygon_no',$thp_cover->polygon_no)->get();
// $polygon_lat_lng_Arr = array();
// foreach ($therapist_coverages as $coverages) {
// $longitude = $coverages->lng;
// $latitude = $coverages->lat;
// $polygon_lat_lng_Arr[] = $longitude.' '.$latitude;
// }
// $longitude_x = $addr_longitude; // x-coordinate of the point to test
// $latitude_y = $addr_latitude; // y-coordinate of the point to test
// //echo $point = $longitude_x.' '.$latitude_y;
// $point = $latitude_y.' '.$longitude_x;
// //print_r($polygon_lat_lng_Arr);
// if (UserCoverageArea::pointInPolygon($point, $polygon_lat_lng_Arr)){
// $is_in_polygon++;
// }
// //echo $is_in_polygon;
// }
// }
// if(!empty($addr_longitude) && !empty($addr_latitude)){
// if($is_in_polygon > 0){
// $is_in_polygon = 0;
// $user_profile = DB::table("users_profile")->where("user_id", $th->id)->first();
// if($user_profile->massage_me_now){
// $unavailable_user_results[] = $th;
// }
// }
// }
// }
// }
$allUsers = array();
if ($usersAvailable) {
$allUsers['available'] = $users;
}
if ($usersUnAvailable) {
$allUsers['unavailable'] = $usersUnAvailable;
}
//return results
return $allUsers;
}
public function salon_th_hours($date, $therapistId)
{
$booking = Session::get('booking');
$session = Session::all();
// dd($session['cartItem']->duration_id);
$bookingPrice = 0;
if (!isset($session['cartItem']) && $this->defaultServiceDuration) {
Session::set('booking.duration', $this->defaultServiceDuration->id);
$bookingDuration = $this->defaultServiceDuration;
$bookingPrice = $bookingDuration->price;
// return $bookingPrice;
// dd($bookingDuration);
} else {
$bookingDuration = SalonServiceDuration::find($session['cartItem']->duration_id);
$bookingPrice = $bookingDuration->price;
// dd("here");
}
// return $bookingPrice;
//hours collection
$hours = [];
//get today
$today = Carbon::today();
//cast current date into Carbon object
$dateC = Carbon::createFromFormat('Y-m-d', $date)->startOfDay();
$diff = $today->diffInHours($dateC, false);
if ($diff < 0)
return $hours;
//the buffer between bookings
$buffer = 10;
//if selected date is marked as day off, return empty hours array
$daysOff = $this->days_off($date);
if ($daysOff->count())
return $hours;
//get weekday working hours: if weekday is non working day, return
$weekday = date('w', strtotime($dateC->format('Y-m-d')));
$whours = Schedule::where('weekday', $weekday)->where('open', 1)->first();
if (!$whours)
return $hours;
//create working hours interval collection
$start = strtotime($whours->bo_start);
$end = strtotime($whours->bo_end);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 0,
'hour' => date('H:i', $start),
'price' => $bookingPrice,
'is_booking' => false,
];
//add remaining hours
while ($start !== $end) {
$start = strtotime('+10 minutes', $start);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 0,
'hour' => date('H:i', $start),
'price' => $bookingPrice,
'is_booking' => false,
'here' => true
];
} //endwhile
$therapist = User::where('id', $therapistId)->first();
$th_hours = [];
$twd = $therapist->workingdays()->where('dayoff', 0)->where('weekday', $weekday)->first();
if ($twd) {
$blockedHours = $therapist->blockedSalonHours($date);
// dd($blockedHours);
if (count($blockedHours)) {
foreach ($this->process_salon_th_hours($twd->bo_start, $twd->bo_end, $blockedHours, $therapist, $date) as $key => $value) {
if (isset($th_hours[$key]) && $th_hours[$key]['available'] == 0)
continue;
else
$th_hours[$key] = $value;
} //endforeach
} else {
foreach ($this->process_salon_th_hours($twd->bo_start, $twd->bo_end, null, $therapist, $date) as $key => $value) {
// dd($value);
if (isset($th_hours[$key]) && $th_hours[$key]['available'] == 0)
continue;
else
$th_hours[$key] = $value;
} //endforeach
}
} //endif
$results = array_merge($hours, $th_hours);
// dd($results);
//available hours based on current duration selection and therapist schedule
if (isset($session['cartItem'])) {
$unvhours = [];
$duration = SalonServiceDuration::find($session['cartItem']->duration_id)->duration;
$collection = collect($results);
$unavailable = $collection->filter(function ($value, $key) {
return $value['available'] == 0;
});
$unavailable->all();
//dd($unavailable, $results);
foreach ($results as $key => $result) {
if ($result['is_booking']) {
$addedMinutes = $duration + $buffer;
$subMinutes = $duration + $buffer;
} else {
$addedMinutes = $duration;
$subMinutes = 0;
}
$start_hour_after = Carbon::createFromFormat('H:i', $key)->addMinutes($addedMinutes);
$start_after = $start_hour_after->format('H:i');
$start_hour_before = Carbon::createFromFormat('H:i', $key)->subMinutes($subMinutes);
$start_before = $start_hour_before->format('H:i');
$end = strtotime($key);
$start = strtotime($start_before);
if ($result['is_booking']) {
//dd($start_before, $key);
}
//add remaining hours
/*while ($start <= $end)
{
$key = date('H:i', $start);
if(isset($results[$key]))
{
$results[$key]['available'] = 0;
}
$start = strtotime('+30 minutes',strtotime($key));
}*/ //endwhile
$ukeys = [];
if ($subMinutes > 0) {
for ($i = $start; $i <= $end; $i = strtotime('+10 minutes', $i)) {
$ukey = date('H:i', $i);
if (isset($results[$ukey])) {
$results[$ukey]['available'] = 0;
}
$ukeys[] = $ukey;
}
//dd($ukeys);
}
foreach ($unavailable as $k => $item) {
if (strtotime($start_after) > strtotime($k)) {
$results[$key]['available'] = 0;
$unavailable->pull($k);
break;
}
}
}
} //endif
//available hours for today based on current time
if ($today->format('Y-m-d') == $dateC->format('Y-m-d')) {
//create disabled hours array for today
$next_time = 60 - Carbon::now()->format('i') + 30;
$first_av_hour = Carbon::now()->addMinutes($next_time)->format('H:i');
foreach ($results as $hour => $values) {
if (strtotime($hour) < strtotime($first_av_hour)) {
$results[$hour]['available'] = 0;
//if hour is set on unavailable time, reset it with the first available hour
if (isset($booking['hour']) && $booking['hour'] == $hour) {
$booking['hour'] = $first_av_hour;
Session::put('booking', $booking);
}
} //endif
} //ensdforeach
} //endif
//if (selected hour is not available, deselect it and save the new session value)
if (isset($booking['hour']) && @$results[$booking['hour']]['available'] == 0) {
$booking['hour'] = null;
unset($booking['hour']);
Session::put('booking', $booking);
} //endif
// dd($results);
//return hours
return collect($results);
}
protected function process_salon_th_hours($starth, $endh, $excepts = [], $th, $date)
{
$booking = Session::get('booking');
$session = Session::all();
$bookingPrice = 0;
if (!isset($session['cartItem']) && $this->defaultServiceDuration) {
Session::set('booking.duration', $this->defaultServiceDuration->id);
$bookingDuration = $this->defaultServiceDuration;
$bookingPrice = $bookingDuration->discounted_price;
} else {
$bookingDuration = SalonServiceDuration::find($session['cartItem']->duration_id);
$bookingPrice = $bookingDuration->discounted_price;
// dd($bookingPrice, $bookingDuration);
}
$hours = [];
$start = strtotime($starth);
$end = strtotime($endh);
$currentHourStart = date('H', $start);
$currentMinuteStart = date('i', $start);
if ($currentMinuteStart > 0 && $currentMinuteStart < 30) {
$start = strtotime('+' . (30 - $currentMinuteStart) . ' minutes', $start);
} elseif ($currentMinuteStart > 30) {
$start = strtotime('+1 hour', $start);
}
//first hour
$key = date('H:i', $start);
$hours[$key] = [
'available' => 1,
'hour' => date('H:i', $start),
'price' => $bookingPrice,
'is_booking' => $th->isBookingHour($date, $key)
];
//add remaining hours
while ($start !== $end) {
$start = strtotime('+10 minutes', $start);
$key = date('H:i', $start);
$hours[$key] = [
'available' => 1,
'hour' => date('H:i', $start),
'price' => $bookingPrice,
'is_booking' => $th->isBookingHour($date, $key)
];
}
// dd($excepts);
//remove hours
if (!empty($excepts)) {
foreach ($excepts as $ex) {
$hours[$ex]['available'] = 0;
$hours[$ex]['price'] = $bookingPrice;
$hours[$ex]['is_booking'] = $th->isBookingHour($date, $ex);
}
}
//return hours
return $hours;
}
/**
* Remove item from basket
* @param Request $request
*/
public function cancel_cart($itemId)
{
//remove item from cart
\Cart::remove($itemId);
$sesTh = BasketTherapist::where('basket_item_id', $itemId)
->get();
if ($sesTh) {
foreach ($sesTh as $sth)
$sth->delete();
} //endif
$sesCodes = BasketVoucher::where('basket_item_id', $itemId)
->get();
if ($sesCodes) {
foreach ($sesCodes as $scode)
$scode->delete();
} //endif
//return response
return response('success', 200);
}
}