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/app/Modules/Schedules/Http/Controllers/Frontend/ |
<?php
namespace App\Modules\Schedules\Http\Controllers\Frontend;
use App\Events\CheckExtensionBasketEvent;
use App\Http\Controllers\SiteController;
use App\Modules\Banners\Repositories\BannersRepo;
use App\Modules\Invoices\Repositories\BookingInvoiceRepository;
use App\Modules\Notifications\Facades\NotifRepository;
use App\Modules\Postcodes\Models\TransportCost;
use App\Modules\Schedules\Http\Requests\CardPayRequest;
use App\Modules\Schedules\Models\BasketTherapist;
use App\Modules\Schedules\Models\BasketVoucher;
use App\Modules\Schedules\Models\BookingOrder;
use App\Modules\Schedules\Models\Order;
use App\Modules\Schedules\Repositories\BookingClass;
use App\Modules\Schedules\Repositories\BookingRepository;
use App\Modules\Services\Models\FocalPoint;
use App\Modules\Services\Models\ServiceDuration;
use App\Modules\Services\Models\ServiceType;
use App\Modules\Services\Models\SalonCategory;
use App\Modules\Schedules\Models\SalonCart;
use App\Modules\Postcodes\Models\Postcode;
use App\Modules\Users\Models\UserBillingAddress;
use App\Modules\Vouchers\Repositories\VoucherRepository;
use App\User;
use App\PendingPayment;
use Carbon\Carbon;
use Darryldecode\Cart\Cart;
use Darryldecode\Cart\CartCondition;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
//use Laravel\Cashier\BraintreeService;
use Mail;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\Request;
use Laracasts\Flash\Flash;
use Mockery\CountValidator\Exception;
use Omnipay\Common\CreditCard;
use Omnipay\Omnipay;
use App\Modules\Users\Models\UserServiceDuration;
use App\Modules\Users\Models\UserCoverageArea;
class BasketController extends SiteController
{
/**
* The book repository instance
*
* @var BookingRepository
*/
protected $book;
protected $ttl;
protected $order_table_hours_limit;
/**
* Create a new controller instance.
*/
public function __construct(BannersRepo $banners, BookingClass $book)
{
parent::__construct($banners);
$this->book = $book;
//time to live item basket: in minutes
$this->ttl = 5;
//user can order table only his booking will be over x hours. for more flexibility and accuracy, the value is in seconds
$this->order_table_hours_limit = 86400;
}
/**
* Book a massage now page
*/
public function index()
{
//create data array
$this->data = [
'meta_title' => 'Basket',
'meta_description' => '',
'meta_keywords' => '',
'basket' => \Cart::getContent()->sortBy('id'),
];
//render page
return view('schedules::frontend_new.basket.basket',$this->data);
}
/**
* Add products to
* @param int $checkout
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
// public function addBack($checkout=0)
// {
// $booking = (array)Session::get('booking');
//
// $mandatory_fields = ['postcode','duration','massage','date', 'hour', 'selected_therapists'];
// foreach($mandatory_fields as $field){
// if (!isset($booking[$field])){
// return response(['message'=>'You must select the postcode, massage duration, type of massage, date of massage, desired hour, the therapist and the focal points'],403);
// }
// } //endforeach
//
// //the therapists number must be equal with selected therapists
// if (count($booking['selected_therapists']) != $booking['therapists'])
// return response(['message'=>'Please choose one more therapist!'],403);
//
// if (!isset($booking['focal_points']))
// $booking['focal_points'] = [];
//
// $therapists = $this->book->selected_therapists();
// $duration = ServiceDuration::where('id',$booking['duration'])->first();
// $massage_type = ServiceType::where('id',$booking['massage'])->first();
// $objfp = FocalPoint::select('name')->whereIn('id',$booking['focal_points'])->get();
//
// switch ($booking['therapists_opt']){
// case '4hands':{
// $quantity=1;
// $price = $duration->price*2;
// break;
// }
// default:{
// $quantity = $booking['therapists'];
// $price = $duration->price;
// break;
// }
// }
//
// $focal_points=[];
// foreach($objfp as $fp)
// $focal_points[] = $fp->name;
//
// $focal_points_string = implode(' / ',$focal_points);
//
// $response = \GoogleMaps::load('textsearch')
// ->setParam([
// 'query' => "{$booking['postcode']} London UK",
// ])->get('results'); // return $this
//
// $googlePlaces = $response['results'][0];
//
//
// //create items cart array
// foreach($therapists as $addth){
// $names[] = $addth->name;
// $images[] = $addth->avatar_url;
// $thIds[] = $addth->id;
// } //end foreach
//
// $itemId = str_random(10);
// $items[] = [
// 'id' => $itemId,
// 'name' => $massage_type,
// 'price' => $price,
// 'quantity' => $quantity,
// 'attributes' => array(
// 'reserved_until' => Carbon::now()->addMinutes(5)->format('Y-m-d H:i:s'),
//// 'reserved_until' => Carbon::now()->addSeconds(10)->format('Y-m-d H:i:s'),
// 'therapist' => $names,
// 'therapistIds' => $thIds,
// 'therapistImage' => $images,
// 'therapistsNo' => $booking['therapists'],
// 'therapistsOpt' => $booking['therapists_opt'],
// 'type' => $booking['type'],
// 'date' => Carbon::createFromFormat('Y-m-d',$booking['date'])->format('d M Y'),
// 'hour'=>$booking['hour'],
// 'duration' => $duration->name,
// 'duration_min' => $duration->duration,
// 'duration_id' => $duration->id,
// 'massage_type' => $massage_type->name,
// 'massage_type_id' => $massage_type->id,
// 'focal_points' => $focal_points_string,
// 'has_table' => false,
// 'has_transport' => false,
// 'transport_cost' => 0,
// 'has_voucher' => false,
// 'user_name' => \Auth::check()?\Auth::user()->name:'',
// 'user_phone' => \Auth::check()?\Auth::user()->profile->mobile_number:'',
// 'address' => $googlePlaces['formatted_address'],
// 'postcode' => $booking['postcode'],
// 'county' => 'London',
// 'location' => $googlePlaces['formatted_address'],
// 'locationGeo' => $googlePlaces['geometry']['location'],
// 'notes' => '',
// ),
// ];
//
// //in the basket can be only one treatment
// if (!\Cart::isEmpty())
// \Cart::clear();
//
// //add items to cart
// \Cart::add($items);
//
// //add travel supplements
// $this->calc_transport_condition($booking,$itemId);
//
// //unset session booking
// Session::forget('booking');
//
// //redirect to basket index
// return response('',200);
// }
/**
* Add items in basket
* @param int $checkout
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
*/
public function add($checkout=0)
{
$cart = \Cart::getContent();
\Cart::clear();
//get booking data from session
$booking = (array)session('booking');
$mandatory_fields = ['postcode','duration','massage','date', 'hour', 'selected_therapists'];
foreach($mandatory_fields as $field){
if (!isset($booking[$field])){
return response(['message'=>'You must select the postcode, massage duration, type of massage, date of massage, desired hour, the therapist and the focal points'],403);
}
} //endforeach
//for massage me now, revalidate booking hour. this is an sensitive hour, because is calculated with google driving class
if (isset($booking['checkArrivalTime']) and $booking['checkArrivalTime']==true){
$users = $this->book->selected_therapists();
$user = $this->book->selected_therapists()->first();
$hour = Carbon::createFromFormat('H:i',$booking['hour']);
$recheckHour = Carbon::createFromFormat('H:i',$this->book->getFirstHour($user,$booking));
$diff = $hour->diffInMinutes($recheckHour);
// return response([
// 'message'=>'test',
// 'booking'=>$booking,
// 'bookingHour'=>$booking['hour'],
// 'diff'=>$diff,
// 'hour'=>$hour,
// 'recheckHour'=>$recheckHour,
// ],403);
//$diff = 0;
if ($diff>3){
//unset hour and therapist
unset($booking['hour']);
unset($booking['selected_therapists']);
Session::put('booking',$booking);
//return error
return response([
'message'=>trans('schedules::booking.message_booking_now_time_passed'),
'booking'=>Session::get('booking'),
],403);
} //endif
} //endif revalidate booking hour for massage me now
//the therapists number must be equal with selected therapists
/*if (count($booking['selected_therapists']) != $booking['therapists'])
return response(['message'=>'Please choose one more therapist!'],403);*/
// if ($cart->count() == $booking['therapists'])
// return response(['message'=>'The maximum number of therapists has been reached for this massage session!'],403);
//add to basket
switch ($booking['therapists_opt']){
case '2_th':{
$productId = $this->add_therapists($booking);
break;
}
case '4hands':{
$productId = $this->add_therapists($booking);
break;
}
default:{
$productId = $test = $this->add_single($booking);
break;
}
} //end switch
//redirect to basket index
return response(['message'=>'The therapist has been selected. Please click on checkout'],200);
}
/**
* Add table condition
* @param Request $request
*/
public function add_table_default($prodId)
{
$this->redirectEmptyBasket();
$productID = $prodId;
$table_value = env('TABLE_VALUE',9.99);
$additional_table = new CartCondition(array(
'name' => 'Massage Table',
'type' => 'addtable',
'target' => 'item',
'value' => $table_value,
'order'=>2,
));
//add table condition to the item cart
\Cart::addItemCondition($productID, $additional_table);
//get item and update attributes has table index
$item = \Cart::get($productID);
$attributes = $item->attributes;
$attributes['has_table'] = true;
$attributes['table_value'] = $table_value;
\Cart::update($productID,array('attributes'=>$attributes));
//return response
$message = [
'success'=>true,
'total'=>"₤ ".$item->getPriceSumWithConditions(),
];
//return response
return response($message,200);
}
/**
* Add item in basket for single massage option
* @param $booking
*/
protected function add_single($booking)
{
$therapists = $this->book->selected_therapists();
$duration = ServiceDuration::where('id',$booking['duration'])->first();
$massage_type = ServiceType::where('id',$booking['massage'])->first();
$quantity = $booking['therapists'];
$bookingDuration = UserServiceDuration::where('services_duration_id', $booking['duration'])
->where('user_id', isset($therapists[0])? $therapists[0]->id:$booking['provider_id'])
->first();
if(!$bookingDuration) {
$price = $duration->price;
} else {
$price = $bookingDuration->price;
}
$vatData = DB::select("SELECT value FROM taxes WHERE id = :id LIMIT 1", ['id' => 2]);
$vat = $vatData[0]->value;
$cartTotal = $price;
$vatAmount = ($cartTotal * ($vat / 100));
$cartTotalAmt = $cartTotal + $vatAmount;
foreach($therapists as $addth){
$names[] = $addth->name;
$images[] = $addth->avatar_url;
$thIds[] = $addth->id;
break;
} //end foreach
//get geo-location with google places
$googlePlaces = $this->getGeoLocation($booking['postcode']);
//get focal points
$focal_points_string = $this->getFocalPoints($booking);
foreach($therapists as $therapist){
if($therapist->services_commisions)
{
if(isset($therapist->services_commisions[$duration->id]))
{
$commision_co = $therapist->services_commisions[$duration->id]['commision_co'];
$commision_th = $therapist->services_commisions[$duration->id]['commision_th'];
}
else
{
$commision_co = $duration->commision_co;
$commision_th = $duration->commision_th;
}
}
else
{
$commision_co = $duration->commision_co;
$commision_th = $duration->commision_th;
}
$itemId = str_random(10);
$item = [
'id' => $itemId,
'name' => $massage_type->name,
'price' => $price,
// 'price' => $price,
'price' => $cartTotalAmt,
'vat_amount' => $vatAmount,
'quantity' => $quantity,
'attributes' => array(
'reserved_until' => Carbon::now()->addMinutes($this->ttl)->format('Y-m-d H:i:s'),
'therapist' => $names,
'therapistIds' => $thIds,
'therapistImage' => $images,
'therapistsNo' => $booking['therapists'],
'therapistsOpt' => $booking['therapists_opt'],
'type' => $booking['type'],
'date' => Carbon::createFromFormat('Y-m-d',$booking['date'])->format('d M Y'),
'hour'=>$booking['hour'],
'duration' => $duration->name,
'duration_min' => $duration->duration,
'duration_id' => $duration->id,
'service_price' => $cartTotal,
'vat_amount' => $vatAmount,
'duration_commision' => [
'company' => $commision_co,
'therapist' => $commision_th,
],
'massage_type' => $massage_type->name,
'massage_type_id' => $massage_type->id,
'focal_points' => $focal_points_string,
'can_order_table' => $this->can_order_table($booking),
'disclaimer' => $this->disclaimer_info($booking),
'has_table' => false,
'has_table_by_default' => $therapist->has_massage_table,
'has_transport' => false,
'transport_cost' => 0,
'has_voucher' => false,
'user_name' => \Auth::check()?\Auth::user()->name:'',
'user_phone' => \Auth::check()?\Auth::user()->profile->mobile_number:'',
'address' => $booking['address'],
'postcode' => $booking['postcode'],
'county' => 'London',
'location' => $booking['address'],
'locationGeo' => $googlePlaces['geometry']['location'],
'notes' => '',
'vat_amount' => $vatAmount
),
];
\Cart::add($item);
$this->calc_transport_condition($booking,$itemId);
//add to session basket
$sesBasket = [
'basket_item_id' => $itemId,
'session_id' => request()->session()->getId(),
'user_id' => \Auth::check()?\Auth::user()->id:'',
'therapist_id' => $therapist->id,
'reserved_until' => $item['attributes']['reserved_until'],
'date' => Carbon::createFromFormat('Y-m-d',$booking['date'])->format('Y-m-d'),
'hour' => $item['attributes']['hour'],
'duration' => $item['attributes']['duration'],
'duration_min' => $item['attributes']['duration_min'],
'duration_id' => $item['attributes']['duration_id'],
];
BasketTherapist::create($sesBasket);
if($therapist->has_massage_table)
{
$this->add_table_default($itemId);
}
} //endforeach
//unset session booking
//Session::forget('booking');
return $itemId;
}
/**
* Add items in basket for 2 therapists massage option
* @param $booking
*/
protected function add_therapists($booking)
{
$therapists = $this->book->selected_therapists();
$duration = ServiceDuration::where('id',$booking['duration'])->first();
$massage_type = ServiceType::where('id',$booking['massage'])->first();
$quantity = 1;
$price = $duration->price;
// foreach($therapists as $addth){
// $names[] = $addth->name;
// $images[] = $addth->avatar_url;
// $thIds[] = $addth->id;
// } //end foreach
//get geo-location with google places
$googlePlaces = $this->getGeoLocation($booking['postcode']);
//get focal points
$focal_points_string = $this->getFocalPoints($booking);
foreach($therapists as $therapist){
$itemId = str_random(10);
if($therapist->services_commisions)
{
if(isset($therapist->services_commisions[$duration->id]))
{
$commision_co = $therapist->services_commisions[$duration->id]['commision_co'];
$commision_th = $therapist->services_commisions[$duration->id]['commision_th'];
}
else
{
$commision_co = $duration->commision_co;
$commision_th = $duration->commision_th;
}
}
else
{
$commision_co = $duration->commision_co;
$commision_th = $duration->commision_th;
}
$item = [
'id' => $itemId,
'name' => $massage_type->name,
'price' => $price,
'quantity' => $quantity,
'attributes' => array(
'reserved_until' => Carbon::now()->addMinutes($this->ttl)->format('Y-m-d H:i:s'),
'therapist' => [$therapist->name],
'therapistIds' => [$therapist->id],
'therapistImage' => [$therapist->avatar_url],
'therapistsNo' => $booking['therapists'],
'therapistsOpt' => $booking['therapists_opt'],
'type' => $booking['type'],
'date' => Carbon::createFromFormat('Y-m-d',$booking['date'])->format('d M Y'),
'hour'=>$booking['hour'],
'duration' => $duration->name,
'duration_min' => $duration->duration,
'duration_id' => $duration->id,
'duration_commision' => [
'company' => $commision_co,
'therapist' => $commision_th,
],
'massage_type' => $massage_type->name,
'massage_type_id' => $massage_type->id,
'focal_points' => $focal_points_string,
'has_table' => false,
'has_table_by_default' => $therapist->has_massage_table,
'can_order_table' => $this->can_order_table($booking),
'disclaimer' => $this->disclaimer_info($booking),
'has_transport' => false,
'transport_cost' => 0,
'has_voucher' => false,
'user_name' => \Auth::check()?\Auth::user()->name:'',
'user_phone' => \Auth::check()?\Auth::user()->profile->mobile_number:'',
'address' => $booking['address'],
'postcode' => $booking['postcode'],
'county' => 'London',
'location' => $booking['address'],
'locationGeo' => $googlePlaces['geometry']['location'],
'notes' => '',
),
];
\Cart::add($item);
$this->calc_transport_condition($booking,$itemId);
//add to session basket
$sesBasket = [
'basket_item_id' => $itemId,
'session_id' => request()->session()->getId(),
'user_id' => \Auth::check()?\Auth::user()->id:'',
'therapist_id' => $therapist->id,
'reserved_until' => $item['attributes']['reserved_until'],
'date' => Carbon::createFromFormat('Y-m-d',$booking['date'])->format('Y-m-d'),
'hour' => $item['attributes']['hour'],
'duration' => $item['attributes']['duration'],
'duration_min' => $item['attributes']['duration_min'],
'duration_id' => $item['attributes']['duration_id'],
];
BasketTherapist::create($sesBasket);
if($therapist->has_massage_table)
{
$this->add_table_default($itemId);
}
} //endforeach
//unset session booking
//Session::forget('booking');
return $itemId;
}
/**
* Add item in baset for the 4hands massage option
* @param $booking
*/
protected function add_4hands($booking)
{
$therapists = $this->book->selected_therapists();
$duration = ServiceDuration::where('id',$booking['duration'])->first();
$massage_type = ServiceType::where('id',$booking['massage'])->first();
$quantity=1;
$price = $duration->price*2;
foreach($therapists as $addth){
$names[] = $addth->name;
$images[] = $addth->avatar_url;
$thIds[] = $addth->id;
} //end foreach
//get geo-location with google places
$googlePlaces = $this->getGeoLocation($booking['postcode']);
//get focal points
$focal_points_string = $this->getFocalPoints($booking);
$itemId = str_random(10);
$item = [
'id' => $itemId,
'name' => $massage_type->name,
'price' => $price,
'quantity' => $quantity,
'attributes' => array(
'reserved_until' => Carbon::now()->addMinutes($this->ttl)->format('Y-m-d H:i:s'),
'therapist' => $names,
'therapistIds' => $thIds,
'therapistImage' => $images,
'therapistsNo' => $booking['therapists'],
'therapistsOpt' => $booking['therapists_opt'],
'type' => $booking['type'],
'date' => Carbon::createFromFormat('Y-m-d',$booking['date'])->format('d M Y'),
'hour'=>$booking['hour'],
'duration' => $duration->name,
'duration_min' => $duration->duration,
'duration_id' => $duration->id,
'duration_commision' => [
'company' => $duration->commision_co,
'therapist' => $duration->commision_th,
],
'massage_type' => $massage_type->name,
'massage_type_id' => $massage_type->id,
'focal_points' => $focal_points_string,
'can_order_table' => $this->can_order_table($booking),
'disclaimer' => $this->disclaimer_info($booking),
'has_table' => false,
'has_transport' => false,
'transport_cost' => 0,
'has_voucher' => false,
'user_name' => \Auth::check()?\Auth::user()->name:'',
'user_phone' => \Auth::check()?\Auth::user()->profile->mobile_number:'',
'address' => $booking['address'],
'postcode' => $booking['postcode'],
'county' => 'London',
'location' => $booking['address'],
'locationGeo' => $googlePlaces['geometry']['location'],
'notes' => '',
),
];
\Cart::add($item);
$this->calc_transport_condition($booking,$itemId);
//add to session basket
foreach($therapists as $therapist){
$sesBasket = [
'basket_item_id' => $itemId,
'session_id' => request()->session()->getId(),
'user_id' => \Auth::check()?\Auth::user()->id:'',
'therapist_id' => $therapist->id,
'reserved_until' => $item['attributes']['reserved_until'],
'date' => Carbon::createFromFormat('Y-m-d',$booking['date'])->format('Y-m-d'),
'hour' => $item['attributes']['hour'],
'duration' => $item['attributes']['duration'],
'duration_min' => $item['attributes']['duration_min'],
'duration_id' => $item['attributes']['duration_id'],
];
BasketTherapist::create($sesBasket);
} //end foreach
//unset session booking
//Session::forget('booking');
return $itemId;
}
/**
* Add item in basket for single massage option
* @param $booking
*/
public function extend_booking_check(BookingOrder $booking, ServiceDuration $extension)
{
//set default response message
$response = ['message'=>trans('schedules::booking.message_error_extension_overlap')];
//validate the booking and the extension
//the booking must be owned by
if ($booking->user_id!=Auth::user()->id || !$booking || !$extension){
$response['message'] = trans('schedules::booking.message_error_extension_access_denied');
return response($response,403);
} //endif
//check extension availability
$can_extend = $this->book->can_extend_with($booking,$extension);
//if cant extend, return response
if (!$can_extend)
return response($response,403);
//create extension ttl
$ttl_min = 1;
$reservedDateLimit = Carbon::now()->addMinutes($ttl_min);
//add to session
$extensionProduct = [
'id' => 'extension_'.$booking->id,
'name' => $extension->name,
'price'=>$extension->price,
'quantity'=>1,
'attributes' => [
'booking_id' => $booking->id,
'booking_obj' => $booking,
'duration' => $extension->name,
'duration_min' => $extension->duration,
'duration_id' => $extension->id,
'duration_commision' => [
'commision_co' => $extension->commision_co,
'commision_th' => $extension->commision_th,
],
'reserved_until' => $reservedDateLimit->format('Y-m-d H:i:s'),
]
];
$cartID = 'extension_'.$booking->id;
$cart = app('cart_extension');
//delete from extension basket the therapists and extension service
$sesExtBasket = BasketTherapist::where('session_id',request()->session()->getId())->delete();
$cart->clear();
//add extension service to cart
$cart->add($extensionProduct);
//add extension to the session_therapist_basket
foreach($booking->therapists as $therapist){
//add basket session table
$sesBasket = [
'basket_item_id' => $cartID,
'session_id' => request()->session()->getId(),
'user_id' => \Auth::check()?\Auth::user()->id:'',
'therapist_id' => $therapist->id,
'reserved_until' => $reservedDateLimit->format('Y-m-d H:i:s'),
'date' => $booking->date->format('Y-m-d'),
'hour' => Carbon::createFromFormat('H:i',$booking->hour)->addMinutes($booking->duration_min)->format('H:i'),
'duration' => $extension->name,
'duration_min' => $extension->duration,
'duration_id' => $extension->id,
];
BasketTherapist::create($sesBasket);
} //endforeach
//return response
return response(['message'=>'You can extend your booking. You have '.$ttl_min.' minutes to confirm your extension. Hurry up!'],200);
}
/**
* Extension Checkout Page
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function extend_booking_checkout()
{
$this->redirectEmptyExtensionBasket();
//get cart extension instance
$cart = app('cart_extension');
//the cart may have only one item and one booking to extend
$item=null;
$booking=null;
$min_ttl = null;
foreach($cart->getContent() as $item){
$booking = $item->attributes->booking_obj;
break;
} //endforeach
//calculate ttl
if ($item){
$reserved_until=\Carbon\Carbon::createFromFormat('Y-m-d H:i:s',$item->attributes->reserved_until);
$reserved_ttl = \Carbon\Carbon::now()->diffInSeconds($reserved_until,false);
if (!$min_ttl)
$min_ttl = $reserved_ttl;
elseif ($min_ttl>$reserved_ttl)
{
$min_ttl = $reserved_ttl;
} //end elseif
} //end item exists
//create data array
$this->data = [
'meta_title' => 'Checkout',
'meta_description' => '',
'meta_keywords' => '',
'booking' => $booking,
'basket_item' => $item,
'min_ttl' => $min_ttl,
'user' => \Auth::user(),
];
//render page
return view('schedules::frontend.extension.checkoutpay',$this->data);
}
/**
* Determine if user can order table. This method is used to compute item basket attribute names can_order_table
* @param $booking
* @return bool
*/
protected function can_order_table($booking)
{
//default value is false
$status = false;
//transform booking hour and time in carbon date-time format
$datehour = Carbon::createFromFormat('Y-m-d H:i',$booking['date']." ".$booking['hour']);
//calculate difference with current time
$diff = Carbon::now()->diffInSeconds($datehour,false);
//set status value
if ($diff < $this->order_table_hours_limit)
$status=false;
else
$status=true;
//return status
return $status;
}
/**
* Checkout disclaimer
* @param $booking
* @return null|string|\Symfony\Component\Translation\TranslatorInterface
*/
protected function disclaimer_info($booking)
{
$status = null;
if (!isset($booking['disclaimer']))
return $status;
switch($booking['disclaimer']){
case 'now':
$status = trans('schedules::booking.message_disclaimer_massagemenow');
break;
} //endswitch
//return status disclaimer
return $status;
}
/**
* Get google location based on user postcode
* @param $booking
* @return mixed
*/
protected function getGeoLocation($postcode)
{
// $response = \GoogleMaps::load('textsearch')
// ->setParam([
// 'query' => "{$postcode} London UK",
// ])->get('results'); // return $this
$response = \GoogleMaps::load('geocoding')
->setParam (['address' => "{$postcode} London UK"])
->get('results');
if ($response['results'])
$geoLocation = $response['results'][0];
else
$geoLocation=null;
//return geolocation
return $geoLocation;
}
/**
* Get focal points for basket booking
* @param $booking
* @return string
*/
protected function getFocalPoints($booking)
{
if (!isset($booking['focal_points']))
$booking['focal_points'] = [];
$objfp = FocalPoint::select('name')->whereIn('id',$booking['focal_points'])->get();
$focal_points=[];
foreach($objfp as $fp)
$focal_points[] = $fp->name;
$response = implode(' / ',$focal_points);
//return response
return $response;
}
/**
* Add transport cost
* @param Request $request
*/
// public function calc_transport_condition($booking,$productID)
// {
// //initialize default cost value
// $cost = 0;
//
// //get massage location district
// $postcode = Postcode::where('postcode',$booking['postcode'])->first();
// $postcode_district = $postcode->zone->district()->first();
//
// //get selected therapists
// $users = User::whereIn('id',$booking['selected_therapists'])->get();
//
// //calculate transport cost for each selected therapist
// foreach($users as $user){
// $district = $user->profile->district;
// $transportCost = TransportCost::where('from_id',$district->id)
// ->where('to_id',$postcode_district->id)
// ->first();
// $cost += $transportCost->price;
// } //endforeach
//
// //return cost
// if (!$cost)
// return;
//
// //get item cart
// $item = \Cart::get($productID);
//
// $costValue = $cost;
// if ($item->quantity>1)
// $costValue = $costValue/2;
//
//
// //add voucher condition
// $travel_cond = new CartCondition(array(
// 'name' => 'Travel supplements',
// 'type' => 'cost',
// 'target' => 'item',
// 'value' => $costValue,
// 'order'=>3,
// ));
//
// //add travel supplements condition to the item cart
// \Cart::addItemCondition($productID, $travel_cond);
//
// $attributes = $item->attributes;
// $attributes['has_transport'] = true;
// $attributes['transport_cost'] = $cost;
//
// \Cart::update($productID,array('attributes'=>$attributes));
// }
public function calc_transport_condition($booking,$productID)
{
//get item cart
$item = \Cart::get($productID);
//initialize default cost value
$cost = 0;
//get massage location district
// $postcode = Postcode::where('postcode',$item->attributes->postcode)->first();
// $postcode_district = $postcode->zone->district()->first();
// //get selected therapists
// $users = User::whereIn('id',$item->attributes->therapistIds)->get();
// //calculate transport cost for each selected therapist
// foreach($users as $user){
// $district = $user->profile->district;
// if ($district){
// $transportCost = TransportCost::where('from_id',$district->id)
// ->where('to_id',$postcode_district->id)
// ->first();
// $cost += $transportCost->price;
// }
// } //endforeach
// 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 cost in travel cost locations
$users = $item->attributes->therapistIds;
$region_travel_cost = 0;
// $users = User::whereIn('id',$item->attributes->therapistIds)->get();
if(!empty($users)){
foreach($users as $th){
$is_in_polygon = 0;
$therapists_id = $th;
$therapist_coverages_1 = DB::table("therapists_travel_costs")->where('user_id',$therapists_id)->get();
$therapist_coverages_last = DB::table("therapists_travel_costs")->where('user_id',$therapists_id)->orderBy('id','DESC')->first();
// if(!empty($therapist_coverages_last->polygon_no)){
// for ($i = 0; $i <= $therapist_coverages_last->polygon_no; $i++) {
// $therapist_coverages = DB::table("therapists_travel_costs")->where('user_id',$therapists_id)->where('polygon_no',$therapist_coverages_last->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;
// $region_travel_cost = $coverages->price;
// }
// $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($therapist_coverages_last->polygon_no)){
foreach($therapist_coverages_1 as $thp_cover){
//for ($i = 0; $i <= $therapist_coverages_last->polygon_no; $i++) {
$therapist_coverages = DB::table("therapists_travel_costs")->where('user_id',$therapists_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;
$region_travel_cost1 = $coverages->price;
}
$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++;
$region_travel_cost = $region_travel_cost1;
//echo $region_travel_cost;
}
}
}
if(!empty($addr_longitude) && !empty($addr_latitude)){
if($is_in_polygon > 0){
$is_in_polygon = 0;
$cost += $region_travel_cost;
}
}
}
}
//die();
//return cost
if (!$cost)
return;
$costValue = $cost;
if ($item->quantity>1)
$costValue = $costValue/2;
//add voucher condition
$travel_cond = new CartCondition(array(
'name' => 'Travel supplements',
'type' => 'cost',
'target' => 'item',
'value' => $costValue,
'order'=>3,
));
//add travel supplements condition to the item cart
\Cart::addItemCondition($productID, $travel_cond);
$attributes = $item->attributes;
$attributes['has_transport'] = true;
$attributes['transport_cost'] = $cost;
\Cart::update($productID,array('attributes'=>$attributes));
}
/**
* Update item id info
* @param Request $request
*/
public function update(Request $request)
{
//get input request
$i = $request->all();
//all fields must be set
if (!$i['name'] || !$i['itemId'])
return response(['message'=>"not allowed"],403);
//allow only fields
$allowed_names = ['user_name','user_phone','address','notes','county'];
if (!in_array($i['name'],$allowed_names))
return response(['message'=>"not allowed"],403);
//get item cart and update value
$item = \Cart::get($i['itemId']);
$attributes = $item->attributes;
$attributes[$i['name']] = $i['value'];
\Cart::update($i['itemId'],array('attributes'=>$attributes));
//return success
return response(['success'=>true],200);
}
/**
* Update item id info
* @param Request $request
*/
public function updateSalon(Request $request)
{
//get input request
$i = $request->all();
//all fields must be set
if (!$i['name'] || !$i['itemId'])
return response(['message'=>"not allowed"],403);
//allow only fields
$allowed_names = ['user_name','user_phone','address','notes','county'];
if (!in_array($i['name'],$allowed_names))
return response(['message'=>"not allowed"],403);
//get item cart and update value
$item = SalonCart::find($i['itemId']);
$item->{$i['name']} = $i['value'];
$item->save();
//return success
return response(['success'=>true],200);
}
/**
* Remove item from basket
* @param Request $request
*/
public function cancel(Request $request)
{
$productID = $request->itemId;
//remove item from cart
\Cart::remove($productID);
//delete all basket from session tables
$session_id = $request->session()->getId();
$sesTh = BasketTherapist::where('session_id',$session_id)
->where('basket_item_id',$productID)
->get();
if ($sesTh){
foreach($sesTh as $sth)
$sth->delete();
} //endif
$sesCodes = BasketVoucher::where('session_id',$session_id)
->where('basket_item_id',$productID)
->get();
if ($sesCodes){
foreach($sesCodes as $scode)
$scode->delete();
} //endif
//return response
return response('success',200);
}
public function cancelCart(Request $request)
{
$cart = \Cart::getContent();
if (!$cart->isEmpty()) {
// Cart is not empty
$itemIds = $cart->keys()->all();
$itemID = $itemIds[0];
$this->book->cancel_cart($itemID);
}
return response('success',200);
}
public function saloncancel(Request $request)
{
$productID = $request->itemId;
// dd($productID);
//remove item from cart
// \Cart::remove($productID);
$cart = SalonCart::where('id', $productID)->delete();
$cartCount = SalonCart::where('user_id', Auth::user()->id)->count();
//delete all basket from session tables
$session_id = $request->session()->getId();
$sesTh = BasketTherapist::where('user_id', Auth::user()->id)
->where('basket_item_id',$productID)
->get();
if ($sesTh){
foreach($sesTh as $sth)
$sth->delete();
} //endif
$sesCodes = BasketVoucher::where('session_id',$session_id)
->where('basket_item_id',$productID)
->get();
if ($sesCodes){
foreach($sesCodes as $scode)
$scode->delete();
} //endif
//return response
// return response()->json([
// 'success' => true,
// 'cartCount' => $cartCount
// ]);
return response($cartCount,200);
}
/**
* Clear basket
* @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
*/
public function cancel_all(Request $request)
{
//clear basket
\Cart::clear();
//delete all basket from session tables
$session_id = $request->session()->getId();
$sesTh = BasketTherapist::where('session_id',$session_id)->get();
if ($sesTh){
foreach($sesTh as $sth)
$sth->delete();
} //endif
$sesCodes = BasketVoucher::where('session_id',$session_id)->get();
if ($sesCodes){
foreach($sesCodes as $scode)
$scode->delete();
} //endif
//return response
return response('success',200);
}
/**
* Add table condition
* @param Request $request
*/
public function add_table(Request $request)
{
$this->redirectEmptyBasket();
$productID = $request->itemId;
$table_value = env('TABLE_VALUE',9.99);
//check again if table can be added to the basket
$check = \Cart::get($productID);
//cannnot order table if the area is not covered
$postCode = Postcode::where('postcode',$check->attributes->postcode)->first();
$district = $postCode->zone->district()->first();
$deliverInArea = (bool)$district->table_restriction->display;
if (!$deliverInArea){
return response(['success'=>false,'message'=>trans('schedules::booking.massage_table_not_deliverable')],403);
}
//cannot order table only over 24h
if (!$check->attributes->can_order_table){
return response(['success'=>false,'message'=>trans('schedules::booking.massage_table_24_notice')],403);
} //endif
$additional_table = new CartCondition(array(
'name' => 'Massage Table',
'type' => 'addtable',
'target' => 'item',
'value' => $table_value,
'order'=>2,
));
//add table condition to the item cart
\Cart::addItemCondition($productID, $additional_table);
//get item and update attributes has table index
$item = \Cart::get($productID);
$attributes = $item->attributes;
$attributes['has_table'] = true;
$attributes['table_value'] = $table_value;
\Cart::update($productID,array('attributes'=>$attributes));
//return response
$message = [
'success'=>true,
'total'=>"₤ ".$item->getPriceSumWithConditions(),
];
//return response
return response($message,200);
}
/**
* Remove table condition
* @param Request $request
*/
public function remove_table(Request $request)
{
$this->redirectEmptyBasket();
$productID = $request->itemId;
//remove table condition from the item table
\Cart::removeItemCondition($productID, $conditionName="Massage Table");
//get item
$item = \Cart::get($productID);
$attributes = $item->attributes;
$attributes['has_table'] = false;
$attributes['table_value'] = 0;
\Cart::update($productID,array('attributes'=>$attributes));
//return response
$message = [
'success'=>true,
'total'=>"₤ ".$item->getPriceSumWithConditions(),
];
//return response
return response($message,200);
}
/**
* Add table condition
* @param Request $request
*/
public function add_voucher(Request $request)
{
$this->redirectEmptyBasket();
$productID = $request->itemId;
//get item cart
$item = \Cart::get($productID);
$appliedCond = collect($item->conditions);
//check if item has already voucher applied
if ($item->attributes->has_voucher)
return response(['success'=>false,'message'=>"You can add only one voucher or code!"],403);
//get voucher code
$checkVoucher = new VoucherRepository();
$voucher = $checkVoucher->validate_voucher($request->value,$productID);
//if voucher is not valid, return response with message
if (!$voucher['valid'])
return response($voucher['message'],403);
//compose condition amount/percent
if ($voucher['voucher']->type=="value"){
$condValue = -($voucher['voucher']->value > $item->getPriceSum()?$item->getPriceSum():$voucher['voucher']->value);
}
else
{
//the value is as percentage
$condValue = -$voucher['voucher']->value."%";
}
//add voucher condition
$additional_voucher = new CartCondition(array(
'name' => 'Voucher',
'type' => 'Voucher',
'target' => 'item',
'value' => $condValue,
'order'=>0,
));
// dd($additional_voucher);
//add table condition to the item cart
\Cart::addItemCondition($productID, $additional_voucher);
//get item and update attributes has table index
$item = \Cart::get($productID);
$attributes = $item->attributes;
$attributes['has_voucher'] = true;
$attributes['voucher'] = [
'id'=>$voucher['voucher']->id,
'name'=>$voucher['voucher']->name,
'code'=>$voucher['voucher']->code,
'value' => $voucher['voucher']->value,
'type' => $voucher['voucher']->type,
'discount' => $condValue,
];
\Cart::update($productID,array('attributes'=>$attributes));
//add voucher to session basket voucher
$basketVoucher = [
'basket_item_id' => $productID,
'basket_item_value' => $item->getPriceSum(), // basket item value without conditions
'session_id' => $request->session()->getId(),
'voucher_code' => $voucher['voucher']->code,
];
BasketVoucher::create($basketVoucher);
// dd($item);
//return response
$message = [
'success'=>true,
'total'=>"₤ ".$item->getPriceSumWithConditions(),
];
//return response
return response($message,200);
}
/**
* Remove table condition
* @param Request $request
*/
public function remove_voucher(Request $request)
{
$this->redirectEmptyBasket();
$productID = $request->itemId;
//remove table condition from the item table
\Cart::removeItemCondition($productID, $conditionName="Voucher");
//get item
$item = \Cart::get($productID);
$attributes = $item->attributes;
$attributes['has_voucher'] = false;
$attributes['voucher'] = [];
//update cart attributes
\Cart::update($productID,array('attributes'=>$attributes));
//remove from session basket
$sesVoucher = BasketVoucher::where('basket_item_id',$productID)
->where('session_id',$request->session()->getId())
->first();
if ($sesVoucher)
$sesVoucher->delete();
//create response message
$message = [
'success'=>true,
'total'=>"₤ ".$item->getPriceSumWithConditions(),
];
//return response
return response($message,200);
}
/**
* Checkout page
*/
public function checkout()
{
$this->redirectEmptyBasket();
// $booking = (array)Session::get('booking');
// dd($booking);
$basket = \Cart::getContent()->sortBy('id');
// dd($basket);
foreach($basket as $item){
$massage = ServiceType::whereIn('id',[$item['attributes']['massage_type_id']])->get();
if($massage[0]->is_massage == null || $massage[0]->is_massage == 0){
$item['attributes']['has_table_by_default'] = false;
$item['attributes']['has_table'] = false;
}
}
// dd($basket);
//create data array
$this->data = [
'meta_title' => 'Checkout',
'meta_description' => '',
'meta_keywords' => '',
'basket' => $basket,
'user' => \Auth::user(),
];
// dd($this->data);
// dd($basket);
//render page
return view('schedules::frontend_new.basket.checkout',$this->data);
}
/**
* Checkout page and pay option
*/
public function checkoutpay()
{
$this->redirectEmptyBasket();
$payment_method_restrict_to_cash = false;
$check_fields = $this->redirectEmptyBookingUserData();
if (!$check_fields)
return redirect(route('bookings.basket.checkout'));
$min_ttl = null;
foreach(\Cart::getContent() as $item){
//set min order ttl
$reserved_until= \Carbon\Carbon::createFromFormat('Y-m-d H:i:s',$item->attributes->reserved_until);
$reserved_ttl = \Carbon\Carbon::now()->diffInSeconds($reserved_until,false);
if (!$min_ttl)
$min_ttl = $reserved_ttl;
elseif ($min_ttl>$reserved_ttl)
{
$min_ttl = $reserved_ttl;
} //end elseif
} //endforeach
$pay_with_voucher=false;
foreach(\Cart::getContent() as $item){
if ($item->attributes->has_voucher && \Cart::getTotal()==0){
$pay_with_voucher=true;
break;
}
elseif($item->attributes->has_voucher){
//if voucher is used and the value of the voucher is grater than the company commision, restrict payment by cash
$payment_method_restrict_to_cash = (($item->attributes->voucher['discount']*(-1)) >$item->attributes->duration_commision['company'])?true:false;
//if at least one booking has payment restriction, stop the script
if ($payment_method_restrict_to_cash) break;
}
} //endforeach
//create data array
$this->data = [
'meta_title' => 'Checkout and Pay',
'meta_description' => '',
'meta_keywords' => '',
'basket' => \Cart::getContent()->sortBy('id'),
'user' => \Auth::user(),
'payment_method_restrict_to_cash' => $payment_method_restrict_to_cash,
'min_ttl' => $min_ttl,
'pay_with_voucher'=>$pay_with_voucher,
];
//render page
return view('schedules::frontend_new.basket.checkoutpay',$this->data);
}
public function createPaymentIntent(Request $request) {
if (\Cart::isEmpty()){
flash('Your basket is empty. The therapists reservations has overdue.','danger');
return redirect()->route('bookings.basket.index');
} //endif
$paymentMethodId = $request->paymentMethodId;
$amount = \Cart::getTotal() * 100; // Replace with the desired amount in cents
// $amount = 100; // Replace with the desired amount in cents
$currency = 'gbp'; // Replace with the desired currency
$stripeSecretKey = env('stripe_secret_key');
$url = 'https://api.stripe.com/v1/payment_intents';
$data = [
'amount' => $amount,
'currency' => $currency,
'payment_method' => $paymentMethodId,
'confirmation_method' => 'automatic', // Set to 'manual' for preauthorization
'capture_method' => 'manual', // Set to 'manual' for preauthorization
// 'confirm' => false, // Manual confirmation
'payment_method_types' => ['card'], // Allow card payments
];
$data = http_build_query($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $stripeSecretKey,
'Content-Type: application/x-www-form-urlencoded',
]);
try {
$response = curl_exec($ch);
if ($response === false) {
throw new \Exception(curl_error($ch));
}
$responseData = json_decode($response, true);
// dd($responseData);
if (isset($responseData['error'])) {
return response()->json(['error' => $responseData['error']['message']], 500);
} else {
// return response()->json(['client_secret' => $responseData['client_secret']]);
// redirect to temp page for handling the card action for 3d secure
// return redirect(route('bookings.basket.paysuccess'));
return response()->json(['client_secret' => $responseData['client_secret'],
'payment_id' => $responseData['id']]);
}
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
} finally {
curl_close($ch);
}
}
public function pay(CardPayRequest $request) {
// dd($request->all());
if (\Cart::isEmpty()){
flash('Your basket is empty. The therapists reservations has overdue.','danger');
return redirect()->route('bookings.basket.index');
} //endif
$this->payment_pending($request);
return redirect(route('bookings.basket.paysuccess'));
}
public function redirectBack(Request $request) {
if($request->payment_intent) {
$payment_intent = $this->retrievePaymentIntent($request->payment_intent);
$responseData = json_decode($payment_intent->getContent(), true);
// dd(empty($responseData['payment_intent']) , empty($responseData['payment_intent']['status']) , $responseData['payment_intent']['status'] != 'requires_capture');
// dd($responseData);
if(!empty($responseData['payment_intent']) && !empty($responseData['payment_intent']['status']) && $responseData['payment_intent']['status'] == 'requires_capture') {
} else {
flash('Payment Failed. Please try to book again.','danger');
return redirect('/');
}
// dd();
} else {
flash('Payment Failed. Please try to book again.','danger');
return redirect('/');
}
// dd($request->all());
if (\Cart::isEmpty()){
flash('Your basket is empty. The therapists reservations has overdue.','danger');
return redirect()->route('bookings.basket.index');
} //endif
//get current user
$user = User::find(Auth::user()->id);
//get total amount
$total = \Cart::getTotal();
//register payment
DB::beginTransaction();
//Create order
$dataOrder = [
'user_id' => \Auth::user()->id,
'amount' => \Cart::getTotal(),
'type' => 'pending',
];
$order = Order::create($dataOrder);
$voucherRepo = new VoucherRepository();
//create booking orders
$bookingOrders = [];
foreach(\Cart::getContent()as $item){
$allInfo = $item->attributes;
$allInfo['price_net'] = $item->getPriceSum();
unset($allInfo['reserved_until']);
//create order bookings array
$data = [
'order_id' => $order->id,
'user_id' => \Auth::user()->id,
'is_active' => true,
'amount' => $item->getPriceSumWithConditions(),
'date' => Carbon::createFromFormat('d M Y',$item->attributes->date)->format('Y-m-d'),
'hour' => $item->attributes->hour,
'duration' => $item->attributes->duration,
'duration_min' => $item->attributes->duration_min,
'massage_type' => $item->attributes->massage_type,
'address' => $item->attributes->address,
'location' => $item->attributes->location,
'locationGeo' => json_encode($item->attributes->locationGeo),
'orderInfo' => json_encode($allInfo),
'updatedby_id' => \Auth::user()->id,
];
//save booking order
$bookorder = BookingOrder::create($data);
//attach therapists to booking order
foreach($allInfo['therapistIds'] as $thid){
$bookorder->therapists()->attach($thid,[
'date'=>Carbon::createFromFormat('d M Y',$item->attributes->date)->format('Y-m-d'),
'duration'=>$item->attributes->duration_min,
'hour'=>$item->attributes->hour
]);
} //endforeach
//if voucher code was used, mark it as used
if ($item->attributes->has_voucher){
$voucherRepo->mark_as_used($item->attributes->voucher['code'],$item->getPriceSum(),$item->id);
} //end
$bookingOrders[] = $bookorder;
} //endforeach
//add mobile notifications
foreach($bookingOrders as $bo){
$notif_message = trans("schedules::booking.mobile_new_order",['number'=>$bo->id,'date'=>$bo->date_to_human,'hour'=>$bo->hour_to_human]);
$notif_users[] = $bo->user_id;
$boInfo = json_decode($bo->orderInfo,true);
$boTherapistsIds = $boInfo['therapistIds'];
foreach($boTherapistsIds as $thid)
$notif_users[] = $thid;
//store notifications
foreach($notif_users as $user)
NotifRepository::add($user,$notif_message, 'booking', 'New Booking');
} //endforeach
//delete session tables: voucher and therapist
$session_id = $request->session()->getId();
$sesTh = BasketTherapist::where('session_id',$session_id)->get();
if ($sesTh){
foreach($sesTh as $sth)
$sth->delete();
} //endif
$sesCodes = BasketVoucher::where('session_id',$session_id)->get();
if ($sesCodes){
foreach($sesCodes as $scode)
$scode->delete();
} //endif
//start a new thread message
$this->book->create_thread($bookorder);
//commit transaction order details
if ($order){
$data = [
'user_id' => Auth::user()->id,
'payment_id' => $request->payment_intent,
'order_id' => $order->id,
'order_info' => json_encode($order)
];
$payment = PendingPayment::create($data);
if($payment) {
DB::commit();
//clear cart contents
\Cart::clear();
//unset session booking key
//$request->session()->forget('booking');
Session::put('booking.selected_therapists',[]);
//send email
$this->sendEmailCheckout($bookingOrders);
} else {
DB::rollBack();
}
}
else{
DB::rollBack();
}
//redirect to success page
return redirect(route('bookings.basket.paysuccess'));
}
public function retrievePaymentIntent($paymentIntentId)
{
// Your Stripe secret key
$secretKey = env('stripe_secret_key');
// Initialize cURL session
$ch = curl_init();
// Set cURL options
curl_setopt($ch, CURLOPT_URL, "https://api.stripe.com/v1/payment_intents/$paymentIntentId");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $secretKey,
]);
// Execute cURL and capture the response
$response = curl_exec($ch);
// Check for errors
if (curl_errno($ch)) {
return ['error' => 'cURL error: ' . curl_error($ch)];
}
// Close cURL session
curl_close($ch);
// Decode the response JSON
$paymentIntent = json_decode($response);
// Handle the PaymentIntent data as needed
// For example, return it to the client or perform further actions
return ['payment_intent' => $paymentIntent];
}
public function payment_pending($request)
{
if (\Cart::isEmpty()){
flash('Your basket is empty. The therapists reservations has overdue.','danger');
return redirect()->route('bookings.basket.index');
} //endif
//get current user
$user = User::find(Auth::user()->id);
//get total amount
$total = \Cart::getTotal();
//register payment
DB::beginTransaction();
//Create order
$dataOrder = [
'user_id' => \Auth::user()->id,
'amount' => \Cart::getTotal(),
'type' => 'pending',
];
$order = Order::create($dataOrder);
$voucherRepo = new VoucherRepository();
//create booking orders
$bookingOrders = [];
foreach(\Cart::getContent()as $item){
$allInfo = $item->attributes;
$allInfo['price_net'] = $item->getPriceSum();
unset($allInfo['reserved_until']);
//create order bookings array
$data = [
'order_id' => $order->id,
'user_id' => \Auth::user()->id,
'is_active' => true,
'amount' => $item->getPriceSumWithConditions(),
'date' => Carbon::createFromFormat('d M Y',$item->attributes->date)->format('Y-m-d'),
'hour' => $item->attributes->hour,
'duration' => $item->attributes->duration,
'duration_min' => $item->attributes->duration_min,
'massage_type' => $item->attributes->massage_type,
'address' => $item->attributes->address,
'location' => $item->attributes->location,
'locationGeo' => json_encode($item->attributes->locationGeo),
'orderInfo' => json_encode($allInfo),
'updatedby_id' => \Auth::user()->id,
];
//save booking order
$bookorder = BookingOrder::create($data);
//attach therapists to booking order
foreach($allInfo['therapistIds'] as $thid){
$bookorder->therapists()->attach($thid,[
'date'=>Carbon::createFromFormat('d M Y',$item->attributes->date)->format('Y-m-d'),
'duration'=>$item->attributes->duration_min,
'hour'=>$item->attributes->hour
]);
} //endforeach
//if voucher code was used, mark it as used
if ($item->attributes->has_voucher){
$voucherRepo->mark_as_used($item->attributes->voucher['code'],$item->getPriceSum(),$item->id);
} //end
$bookingOrders[] = $bookorder;
} //endforeach
//add mobile notifications
foreach($bookingOrders as $bo){
$notif_message = trans("schedules::booking.mobile_new_order",['number'=>$bo->id,'date'=>$bo->date_to_human,'hour'=>$bo->hour_to_human]);
$notif_users[] = $bo->user_id;
$boInfo = json_decode($bo->orderInfo,true);
$boTherapistsIds = $boInfo['therapistIds'];
foreach($boTherapistsIds as $thid)
$notif_users[] = $thid;
//store notifications
foreach($notif_users as $user)
NotifRepository::add($user,$notif_message, 'booking', 'New Booking');
} //endforeach
//delete session tables: voucher and therapist
$session_id = $request->session()->getId();
$sesTh = BasketTherapist::where('session_id',$session_id)->get();
if ($sesTh){
foreach($sesTh as $sth)
$sth->delete();
} //endif
$sesCodes = BasketVoucher::where('session_id',$session_id)->get();
if ($sesCodes){
foreach($sesCodes as $scode)
$scode->delete();
} //endif
//start a new thread message
$this->book->create_thread($bookorder);
$responseData = '';
//commit transaction order details
if ($order){
if($request->paymentIntentId) {
$payment_intent = $this->retrievePaymentIntent($request->paymentIntentId);
// dd($payment_intent);
$responseData = $payment_intent;
if(!empty($responseData['payment_intent']) && $responseData['payment_intent']->status == 'requires_capture') {
$capturePayment = $this->capturePayment($request->paymentIntentId);
} else {
$capturePayment = $this->confirmPaymentIntent($request->paymentIntentId); // here need to uncomment
}
// Get the data from the JsonResponse and decode it
$responseData = $capturePayment; // here need to uncomment
// $responseData = json_decode($capturePayment, true);
// dd($responseData);
// if(!empty($responseData['error'])) {
// //set success message
// Flash::info($responseData['error']);
// } elseif (!empty($responseData['status'])) {
// //set success message
// Flash::info("Captured Payment Successfully");
// } else {
// //set success message
// Flash::info("Something went wrong! Do it manualy through stripe");
// }
}
$data = [
'user_id' => Auth::user()->id,
'payment_id' => $request->paymentIntentId,
'order_id' => $order->id,
'order_info' => json_encode($order),
'status' => 2,
'response_data' => json_encode($responseData),
];
$payment = PendingPayment::create($data);
if($payment) {
DB::commit();
//clear cart contents
\Cart::clear();
//unset session booking key
//$request->session()->forget('booking');
Session::put('booking.selected_therapists',[]);
//send email
$this->sendEmailCheckout($bookingOrders);
} else {
DB::rollBack();
}
}
else{
DB::rollBack();
}
//redirect to success page
return redirect(route('bookings.basket.paysuccess'));
}
public function capturePayment($paymentIntentId)
{
$stripeSecretKey = env('stripe_secret_key');
$captureUrl = "https://api.stripe.com/v1/payment_intents/$paymentIntentId/capture";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $captureUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $stripeSecretKey,
]);
try {
$response = curl_exec($ch);
if ($response === false) {
throw new \Exception(curl_error($ch));
}
return $responseData = json_decode($response, true);
// if (isset($responseData['error'])) {
// return;
// } else {
// return response()->json(['message' => 'Payment captured successfully']);
// }
} catch (\Exception $e) {
return;
// response()->json(['error' => $e->getMessage()], 500);
} finally {
curl_close($ch);
}
}
public function confirmPaymentIntent($payment_intent_id)
{
$paymentIntentId = $payment_intent_id;
// return $this->capturePayment($paymentIntentId);
$stripeSecretKey = env('stripe_secret_key');
$confirmUrl = "https://api.stripe.com/v1/payment_intents/$paymentIntentId/confirm";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $confirmUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $stripeSecretKey,
]);
try {
$response = curl_exec($ch);
if ($response === false) {
throw new \Exception(curl_error($ch));
}
return $responseData = json_decode($response, true);
// if (isset($responseData['error'])) {
// // dd("inside confirmation",$responseData);
// return response()->json(['error' => $responseData['error']['message']], 500);
// } else {
// // dd("hre");
// // Now that the PaymentIntent is confirmed, you can proceed to capture it.
// return $this->capturePayment($paymentIntentId);
// }
} catch (\Exception $e) {
return ['error' => $e->getMessage()];
} finally {
curl_close($ch);
}
}
/**
* Pay method
* @param Request $request
*/
public function pay_from_admin(CardPayRequest $request)
{
dd($request->all());
$this->redirectEmptyBasket();
$gateway = Omnipay::create('SagePay\Direct');
$gateway->setVendor(env('SAGEPAY_VENDOR_NAME'));
$gateway->setTestMode(env('SAGEPAY_TEST_MODE'));
$total = \Cart::getTotal();
$user = User::find(Auth::user()->id);
$billingAddress = $user->address()->orderBy('is_main','desc')->first();
try {
$card = new CreditCard([
'firstName' => $user->profile->first_name,
'lastName' => $user->profile->last_name,
'number' => $request->card_number, //4462000000000003
'expiryMonth' => $request->expiry_month, //6
'expiryYear' => $request->expiry_year, //2030
'cvv' => $request->card_cvv, //123
//billing
'billingAddress1' => $request->billing_address?: env('SAGEPAY_BILLING_ADDR1'),
'billingCity' => $request->billing_county?: env('SAGEPAY_BILLING_CITY'),
'billingPostcode' => $request->billing_postcode?: env('SAGEPAY_BILLING_POSTCODE'),
'billingCountry' => $request->billing_country?:'GB',
'billingPhone' => $user->profile->mobile_number,
//shipping
'shippingAddress1' => $billingAddress?$billingAddress->address : env('SAGEPAY_BILLING_ADDR1'),
'shippingState' => $billingAddress?$billingAddress->county : env('SAGEPAY_BILLING_CITY'),
'shippingCity' => $billingAddress?$billingAddress->county : env('SAGEPAY_BILLING_CITY'),
'shippingPostcode' => $billingAddress?$billingAddress->postcode : env('SAGEPAY_BILLING_POSTCODE'),
'shippingCountry' => 'GB',
'shippingPhone' => $user->profile->mobile_number,
]);
}
catch(\Exception $e){
flash(strtoupper($e->getMessage()), 'danger');
return redirect(route('bookings.basket.checkoutpay'))->withInput(['error_message'=>$e->getMessage(), 'error_code'=>$e->getCode()]);
}
// dd($card_response->getCardReference());
// $total = 20;
$transactionId = time();
//add to the request
$request->transaction_id = $transactionId;
try {
$response = $gateway->purchase(array(
'amount' => $total,
'currency' => env('SAGEPAY_CCY'),
'card' => $card,
'notifyUrl' => url('sagepay-process'),
'redirectUrl' => url('sagepay-process'),
'transactionId' => $transactionId,
'description' => 'Massage Services',
'billingCountry' => 'GB',
))->send();
//print_r($response); die();
}
catch(\Exception $e){
flash(strtoupper($e->getMessage()), 'danger');
return redirect(route('bookings.basket.checkoutpay'))->withInput(['error_message'=>$e->getMessage(), 'error_code'=>$e->getCode()]);
}
if ($response->isSuccessful()) {
// dd([
// 'code'=>$response->getCode(),
// 'message'=>$response->getMessage(),
// 'transaction_reference'=>$response->getTransactionReference(),
// 'full_responde' => $response->getData(),
// ]);
// return redirect(route('bookings.basket.paysuccess'));
//register payment
$this->register_payment($response,$request);
//save billing address
$billingAddrObj = UserBillingAddress::firstOrCreate([
'address'=>$request->billing_address,
'county'=>$request->billing_county,
'postcode'=>$request->billing_postcode,
'user_id' => \Auth::user()->id
]);
//redirect to success page
return redirect(route('bookings.basket.paysuccess'));
}
elseif ($response->isRedirect()){
return redirect($response->redirect());
}
else{
// dd([
// 'code'=>$response->getCode(),
// 'message'=>$response->getMessage(),
// 'full_responde' => $response->getData(),
// ]);
return redirect(route('bookings.basket.checkoutpay'))->withInput(['error_message'=>$response->getMessage(), 'error_code'=>$response->getCode()]);
}
}
public function pay_test()
{
//print_r($_GET);
$cardno = $_GET['cardno'];
$exp_month = $_GET['exp_month'];
$exp_year = $_GET['exp_year'];
$cvv = $_GET['cvv'];
// Create the gateway object.
$gateway = Omnipay::create('SagePay\Direct');
$gateway->setVendor(env('SAGEPAY_VENDOR_NAME'));
$gateway->setTestMode(false);
echo '<pre>';
// Create the credit card object from details entered by the user.
$transactionId = time();
$card = new CreditCard([
'firstName' => 'Card',
'lastName' => 'User',
'billingFirstName' => 'Joe',
'billingLastName' => 'Bloggs',
'billingAddress1' => 'Billing Address 1',
'billingAddress2' => 'Billing Address 2',
//'billingState' => '',
'billingCity' => 'Billing City',
'billingPostcode' => 'BPOSTC',
'billingCountry' => 'GB',
'billingPhone' => '01234 567 890',
//
'email' => 'test@example.com',
'clientIp' => '123.123.123.123',
//
'shippingFirstName' => 'Joe',
'shippingLastName' => 'Bloggs',
'shippingAddress1' => '99',
'shippingState' => 'NY',
'shippingCity' => 'City1',
'shippingPostcode' => 'SPOSTC',
'shippingCountry' => 'US',
'shippingPhone' => '01234 567 890 SS',
'number' => $cardno,
'expiryMonth' => $exp_month,
'expiryYear' => $exp_year,
'CVV' => $cvv,
]);
// Create the minimal request message.
$requestMessage = $gateway->purchase([
'amount' => '0.5',
'currency' => 'GBP',
'card' => $card,
'transactionId' => $transactionId,
'description' => 'Pizzas for everyone at PHPNE',
// If 3D Secure is enabled, then provide a return URL for
// when the user comes back from 3D Secure authentication.
'returnUrl' => url('sagepay-process'),
]);
// Send the request message.
$response = $requestMessage->send();
if ($response->isSuccessful()) {
// Should never happen for Sage Pay Server, since the user will always
// be asked to go off-site to enter their credit card details.
} elseif ($response->isRedirect()) {
// Redirect to offsite payment gateway to capture the users credit card
// details. Note that no address details are needed, nor are they captured.
// Here add the $response->getTransactionReference() to the stored transaction,
// as the notification handler will need it for checking the signature of the
// notification it receives.
$response->redirect();
} else {
$reason = $response->getMessage();
}
print_r($response);
}
public function pay_old(Request $request)
{
return null;
$this->redirectEmptyBasket();
$total = \Cart::getTotal();
$user = User::find(Auth::user()->id);
$token = $request->input('payment-method-nonce');
//if user has no plans, create one
if (!$user->braintree_id){
try{
$user->newSubscription('single-charge', "qrjb")->create($token,[
'email'=>$user->email,
'phone'=>$user->profile->mobile_phone,
]);
// $user->newSubscription('single-charge', env('BRAINTREE_PLAN','qrjb'))->create($token, [
// 'email' => $user->email,
// 'phone' => $user->profile->mobile_phone,
// ]);
$name = "massage services";
$response = $user->invoiceFor($name,$total);
//register payment
$this->register_payment($response,$request);
}
catch (\Exception $e){
$message = $e->getMessage();
$message = str_ireplace('braintree','Zen London',$message);
flash(strtoupper($message), 'danger');
// flash(strtoupper(trans('schedules::payment.incorrect_card_details')), 'danger');
return redirect(route('bookings.basket.checkoutpay'));
}
}
else{
//update token for each payment
try{
$user->updateCard($token);
$name = "massage services";
$response = $user->invoiceFor($name,$total);
//register payment
$this->register_payment($response,$request);
}
catch (\Exception $e){
$message = $e->getMessage();
$message = str_ireplace('braintree','Zen London',$message);
flash(strtoupper($message), 'danger');
return redirect(route('bookings.basket.checkoutpay'));
}
} //endif
//change user amount
// try {
// $name = "massage services";
// $response = $user->invoiceFor($name,$total);
//// $response = $user->charge($total);
// } catch (\Exception $e) {
//
// $message = $e->getMessage();
// $message = str_ireplace('braintree','Zen London',$message);
//
// flash(strtoupper($message), 'danger');
// return redirect(route('bookings.basket.checkoutpay'));
// }
//redirect to success page
return redirect(route('bookings.basket.paysuccess'));
}
/**
* Pay with existing card
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function pay_with_existing_card(Request $request)
{
$this->redirectEmptyBasket();
//get current user
$user = User::find(Auth::user()->id);
if (!$user->braintree_id){
flash(strtoupper("You have no valid card defined. Please enter one below!"), 'danger');
return redirect(route('bookings.basket.checkoutpay'));
} //end
//get total amount
$total = round(\Cart::getTotal(),2);
//charge user amount
try {
$name = "massage services";
$response = $user->invoiceFor($name,$total);
} catch (\Exception $e) {
$message = $e->getMessage();
$message = str_ireplace('braintree','Zen London',$message);
flash(strtoupper($message), 'danger');
return redirect(route('bookings.basket.checkoutpay'));
}
//register payment
$this->register_payment($response,$request);
//redirect to success page
return redirect(route('bookings.basket.paysuccess'));
}
/**
* Pay with existing card
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function pay_with_cash(Request $request)
{
if (\Cart::isEmpty()){
flash('Your basket is empty. The therapists reservations has overdue.','danger');
return redirect()->route('bookings.basket.index');
} //endif
//get current user
$user = User::find(Auth::user()->id);
//get total amount
$total = \Cart::getTotal();
//register payment
DB::beginTransaction();
//Create order
$dataOrder = [
'user_id' => \Auth::user()->id,
'amount' => \Cart::getTotal(),
'type' => 'cash',
];
$order = Order::create($dataOrder);
$voucherRepo = new VoucherRepository();
//create booking orders
$bookingOrders = [];
foreach(\Cart::getContent()as $item){
$allInfo = $item->attributes;
$allInfo['price_net'] = $item->getPriceSum();
unset($allInfo['reserved_until']);
//create order bookings array
$data = [
'order_id' => $order->id,
'user_id' => \Auth::user()->id,
'is_active' => true,
'amount' => $item->getPriceSumWithConditions(),
'date' => Carbon::createFromFormat('d M Y',$item->attributes->date)->format('Y-m-d'),
'hour' => $item->attributes->hour,
'duration' => $item->attributes->duration,
'duration_min' => $item->attributes->duration_min,
'massage_type' => $item->attributes->massage_type,
'address' => $item->attributes->address,
'location' => $item->attributes->location,
'locationGeo' => json_encode($item->attributes->locationGeo),
'orderInfo' => json_encode($allInfo),
'updatedby_id' => \Auth::user()->id,
];
//save booking order
$bookorder = BookingOrder::create($data);
//attach therapists to booking order
foreach($allInfo['therapistIds'] as $thid){
$bookorder->therapists()->attach($thid,[
'date'=>Carbon::createFromFormat('d M Y',$item->attributes->date)->format('Y-m-d'),
'duration'=>$item->attributes->duration_min,
'hour'=>$item->attributes->hour
]);
} //endforeach
//if voucher code was used, mark it as used
if ($item->attributes->has_voucher){
$voucherRepo->mark_as_used($item->attributes->voucher['code'],$item->getPriceSum(),$item->id);
} //end
$bookingOrders[] = $bookorder;
} //endforeach
//add mobile notifications
foreach($bookingOrders as $bo){
$notif_message = trans("schedules::booking.mobile_new_order",['number'=>$bo->id,'date'=>$bo->date_to_human,'hour'=>$bo->hour_to_human]);
$notif_users[] = $bo->user_id;
$boInfo = json_decode($bo->orderInfo,true);
$boTherapistsIds = $boInfo['therapistIds'];
foreach($boTherapistsIds as $thid)
$notif_users[] = $thid;
//store notifications
foreach($notif_users as $user) {
try{
NotifRepository::add($user,$notif_message, 'booking', 'New Booking');
}catch (\Exception $e) {
}
}
} //endforeach
//delete session tables: voucher and therapist
$session_id = $request->session()->getId();
$sesTh = BasketTherapist::where('session_id',$session_id)->get();
if ($sesTh){
foreach($sesTh as $sth)
$sth->delete();
} //endif
$sesCodes = BasketVoucher::where('session_id',$session_id)->get();
if ($sesCodes){
foreach($sesCodes as $scode)
$scode->delete();
} //endif
//start a new thread message
$this->book->create_thread($bookorder);
//commit transaction order details
if ($order){
DB::commit();
//clear cart contents
\Cart::clear();
//unset session booking key
//$request->session()->forget('booking');
Session::put('booking.selected_therapists',[]);
//send email
$this->sendEmailCheckout($bookingOrders);
}
else{
DB::rollBack();
}
//redirect to success page
return redirect(route('bookings.basket.paysuccess'));
}
/**
* Register payment
* @param $response
*/
protected function register_payment($response,$request)
{
$messageArr = explode(':',$response->getMessage());
$message = trim($messageArr[1]);
// dd([
// 'transactionId' => $request->transaction_id,
// 'transaction_reference' => $response->getTransactionReference(),
// 'security_key' => $response->getSecurityKey(),
// 'full_message'=>$response->getMessage(),
// 'message'=>$message,
// 'status'=>$response->isSuccessful(),
// 'full_data'=>$response->getData(),
// 'cart' => \Cart::getContent(),
// 'request'=>$request,
// ]);
DB::beginTransaction();
//card details
$maskedNumber = substr($request->card_number,0,4).' **** **** '.substr($request->card_number,-4);
$lastFour = substr($request->card_number,-4);
//attach transaction refference to the user
$user = \Auth::user();
$user->card_reference = $response->getTransactionReference();
$user->card_last_four = $lastFour;
$user->save();
//Create order
$dataOrder = [
'user_id' => \Auth::user()->id,
'amount' => \Cart::getTotal(),
'type' => 'card',
'card_trans_id' => $response->getTransactionReference(),
'card_trans_status' => (bool)$response->isSuccessful(),
'card_details' => json_encode([
'customerLocation' => '',
'cardType' => '',
'expirationDate' => $request->expiry_month.'/'.$request->expiry_year,
'imageUrl' => '',
'maskedNumber' => $maskedNumber,
'last4' => $lastFour,
'bin' => '',
'transaction_id' => $request->transaction_id,
'transaction_reference'=>$response->getTransactionReference(),
'security_id'=>$response->getSecurityKey(),
]),
];
$order = Order::create($dataOrder);
$voucherRepo = new VoucherRepository();
//create booking orders
$bookingOrders = [];
foreach(\Cart::getContent()as $item){
$allInfo = $item->attributes;
$allInfo['price_net'] = $item->getPriceSum();
$allInfo['amount'] = $item->getPriceSumWithConditions();
unset($allInfo['reserved_until']);
//create order bookings array
$data = [
'order_id' => $order->id,
'user_id' => \Auth::user()->id,
'is_active' => true,
'amount' => $item->getPriceSumWithConditions(),
'date' => Carbon::createFromFormat('d M Y',$item->attributes->date)->format('Y-m-d'),
'hour' => $item->attributes->hour,
'duration' => $item->attributes->duration,
'duration_min' => $item->attributes->duration_min,
'massage_type' => $item->attributes->massage_type,
'massage_type_id' => $item->attributes->massage_type_id,
'address' => $item->attributes->address,
'location' => $item->attributes->location,
'locationGeo' => json_encode($item->attributes->locationGeo),
'orderInfo' => json_encode($allInfo),
'card_trans_id' => $response->getTransactionReference(),
'card_trans_status' => (bool)$response->isSuccessful(),
'card_details' => json_encode([
'customerLocation' => '',
'cardType' => '',
'expirationDate' => $request->expiry_month.'/'.$request->expiry_year,
'imageUrl' => '',
'maskedNumber' => $maskedNumber,
'last4' => $lastFour,
'bin' => '',
'transaction_id' => $request->transaction_id,
'transaction_reference'=>$response->getTransactionReference(),
'security_id'=>$response->getSecurityKey(),
]),
'updatedby_id' => \Auth::user()->id,
];
//save booking order
$bookorder = BookingOrder::create($data);
//create invoice
if ($response->getTransactionReference()){
$invRepo = new BookingInvoiceRepository();
$invRepo->new_invoice($bookorder);
} //endif
//attach therapists to booking order
foreach($allInfo['therapistIds'] as $thid){
$bookorder->therapists()->attach($thid,[
'date'=>Carbon::createFromFormat('d M Y',$item->attributes->date)->format('Y-m-d'),
'duration'=>$item->attributes->duration_min,
'hour'=>$item->attributes->hour
]);
} //endforeach
//if voucher code was used, mark it as used
if ($item->attributes->has_voucher){
$voucherRepo->mark_as_used($item->attributes->voucher['code'],$item->getPriceSum(),$item->id);
} //end
//start a new thread message
$this->book->create_thread($bookorder);
$bookingOrders[] = $bookorder;
} //endforeach
//delete session tables: voucher and therapist
$session_id = $request->session()->getId();
$sesTh = BasketTherapist::where('session_id',$session_id)->get();
if ($sesTh){
foreach($sesTh as $sth)
$sth->delete();
} //endif
$sesCodes = BasketVoucher::where('session_id',$session_id)->get();
if ($sesCodes){
foreach($sesCodes as $scode)
$scode->delete();
} //endif
//add mobile notifications
foreach($bookingOrders as $bo){
$notif_message = trans("schedules::booking.mobile_new_order",['number'=>$bo->id,'date'=>$bo->date_to_human,'hour'=>$bo->hour_to_human]);
$notif_users[] = $bo->user_id;
$boInfo = json_decode($bo->orderInfo,true);
$boTherapistsIds = $boInfo['therapistIds'];
foreach($boTherapistsIds as $thid)
$notif_users[] = $thid;
//store notifications
foreach($notif_users as $user)
NotifRepository::add($user,$notif_message, 'booking', 'New Booking');
} //endforeach
//commit transaction order details
if ($order){
DB::commit();
//clear cart contents
\Cart::clear();
//unset session booking key
//$request->session()->forget('booking');
Session::put('booking.selected_therapists',[]);
//send email
$this->sendEmailCheckout($bookingOrders);
}
else{
DB::rollBack();
}
}
/**
* Send condfirmation order
* @param $order
*/
public function sendEmailCheckout($orders)
{
$user = User::findOrFail($orders[0]->user_id);
$data['user'] = $user;
$data['orders'] = $orders;
// dd($data);
//send confirmation email
Mail::send('schedules::frontend.emails.neworder', ['user' => $user, 'orders'=>$orders], 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').' – booking confirmation');
});
//send email to therapists
$order = $orders[0];
$boInfo = json_decode($order->orderInfo,true);
$boTherapistsIds = $boInfo['therapistIds'];
$therapists = User::whereIn('id',$boTherapistsIds)->get();
$dataTh['user'] = $therapists;
$dataTh['orders'] = $orders;
foreach($therapists as $therapist){
$dataTh['user'] = $therapist;
Mail::send('schedules::frontend.emails.therapist_neworder', ['user' => $therapist, 'orders'=>$orders], function ($m) use ($dataTh) {
$m->from(env('MAIL_FROM'), env('APP_NAME'));
$m->to($dataTh['user']->email, $dataTh['user']->name);
$m->bcc(explode(',',env('MAIL_NEWORDER_BCC')), env('MAIL_NEWORDER_BCC_NAME'));
$m->subject(env('APP_NAME').' – you have a new booking');
});
} //end foreach
}
/**
* Send condfirmation order
* @param $order
*/
public function sendSalonEmailCheckout($orders)
{
$user = User::findOrFail($orders[0]->user_id);
$data['user'] = $user;
$data['orders'] = $orders;
//send confirmation email
Mail::send('schedules::frontend.emails.salonneworder', ['user' => $user, 'orders'=>$orders], 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').' – booking confirmation');
});
//send email to therapists
$order = $orders[0];
$boInfo = json_decode($order->orderInfo,true);
// dd($data, $boInfo);
$boTherapistsIds = [$boInfo['therapist']['id']];
$therapists = User::whereIn('id',$boTherapistsIds)->get();
$dataTh['user'] = $therapists;
$dataTh['orders'] = $orders;
foreach($therapists as $therapist){
$dataTh['user'] = $therapist;
Mail::send('schedules::frontend.emails.salontherapist_neworder', ['user' => $therapist, 'orders'=>$orders], function ($m) use ($dataTh) {
$m->from(env('MAIL_FROM'), env('APP_NAME'));
$m->to($dataTh['user']->email, $dataTh['user']->name);
$m->bcc(explode(',',env('MAIL_NEWORDER_BCC')), env('MAIL_NEWORDER_BCC_NAME'));
$m->subject(env('APP_NAME').' – you have a new booking');
});
} //end foreach
// for salon
$boTherapistsIds = [$boInfo['salon']['id']];
$therapists = User::whereIn('id',$boTherapistsIds)->get();
$dataTh['user'] = $therapists;
$dataTh['orders'] = $orders;
foreach($therapists as $therapist){
$dataTh['user'] = $therapist;
Mail::send('schedules::frontend.emails.salon_owner_neworder', ['user' => $therapist, 'orders'=>$orders], function ($m) use ($dataTh) {
$m->from(env('MAIL_FROM'), env('APP_NAME'));
$m->to($dataTh['user']->email, $dataTh['user']->name);
$m->bcc(explode(',',env('MAIL_NEWORDER_BCC')), env('MAIL_NEWORDER_BCC_NAME'));
$m->subject(env('APP_NAME').' – you have a new booking');
});
} //end foreach
}
/**
* Redirect for empty basket
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function redirectEmptyBasket()
{
if (\Cart::isEmpty()){
flash('Opps…time files! Your booking has expired! Be quick! But don’t rush!','danger');
return redirect()->route('bookings.basket.index');
} //endif
}
/**
* Redirect for empty basket
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function redirectEmptyExtensionBasket()
{
\Event::fire(new CheckExtensionBasketEvent());
$cart = app('cart_extension');
if ($cart->isEmpty()){
flash('Opps…time files! Your booking extension has expired! Be quick! But don’t rush!','danger');
} //endif
}
/**
* Each booking must have user details
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
protected function redirectEmptyBookingUserData()
{
//mandatory booking user data fields
$check_fields = ['user_name'=>'Full Name','user_phone'=>'Phone number','address'=>'Full Address','postcode'=>'Postcode'];
foreach(\Cart::getContent() as $item){
foreach($check_fields as $field=>$field_name){
if ($item->attributes->$field==""){
flash(trans("schedules::booking.message_error_missing_booking_user_field",['field'=>$field_name]));
// dd("inside if");
return false;
break;
}
if($field == 'user_phone')
{
$isPhone = $this->book->checkPhoneNumber($item->attributes->$field);
if(!$isPhone){
flash(trans("schedules::booking.message_error_format_booking_user_phone",['field'=>$field_name]));
return false;
break;
}
}
} //endforeach
} //endforeach
//all fields are completed
return true;
}
/**
* Checkout success payment page
*/
public function paysuccess()
{
//get user
$user = User::find(\Auth::user()->id);
//get upcoming user bookings
$bookings = $user->bookings()
->select('*',DB::raw('CONCAT_WS(" ",date,hour) as bookingdate'))
->whereRaw(' TIMESTAMPADD(MINUTE,duration_min,CONCAT_WS(" ",date,hour)) >= TIMESTAMP(DATE_SUB(NOW(),INTERVAL 1 HOUR))')
// ->whereRaw(' CONCAT_WS(" ",date,hour) >= NOW()')
// ->whereRaw("date >= DATE(NOW()) AND TIME(ADDTIME(TIME(hour),'0 1:0:0')) > TIME(hour)")
// ->whereRaw('ADDTIME(ADDTIME(hour,STR_TO_DATE(CONCAT(FLOOR(duration_min/60),\':\',MOD(duration_min,60)),"%h:%i")),"0:15") > TIME(NOW())')
->where('is_active',1)
->orderBy('date','asc')
->orderBy('hour','asc')
->get();
if(isset($bookings)){
$data['latest_order_id'] = BookingOrder::orderBy('order_id', 'desc')->whereIn('user_id', [Auth::user()->id])->pluck('order_id')->first();
$data['latest_booking'] = $bookings->where('order_id', $data['latest_order_id'] )->all();
}
$upcoming = $bookings->first();
//create data array
// $data['bookings'] = $bookings;
$data['extensions'] = ServiceDuration::where('is_extra',1)->orderBy('duration','asc')->get();
// $data['upcoming'] = $upcoming;
$data['booking'] = Session::get('booking');
$this->data = [
'meta_title' => 'Checkout and Pay',
'meta_description' => '',
'meta_keywords' => '',
'latest_order_id' => $data['latest_order_id'],
'latest_booking' => $data['latest_booking'],
'bookings' => $bookings,
'extensions' => $data['extensions'],
'upcoming' => $upcoming,
];
// dd($this->data);
//render page
return view('schedules::frontend_new.basket.checkoutsuccess',$this->data);
}
// Salon Section
public function salonCheckout()
{
$booking = Session::get('booking');
// dd($booking);
if(!isset($booking['address'])){
return redirect('/')->withErrors(['msg' => 'Please enter your postal code/address']);
}
if(Auth::user()) {
$cartCount = SalonCart::where('user_id', Auth::user()->id)->count();
$cartDetails = $this->cartContent();
} else {
return redirect('/');
}
// $cartCount = SalonCart::where('user_id', Auth::user()->id)->count();
// if($cartCount <= 0){
// return redirect('/booking/salon/users');
// }
// $cartContent = $BookingsController->cartContent();
// $cart = SalonCart::where('user_id', Auth::user()->id)->get();
// $cartDetails = [];
// foreach($cart as $c){
// $cartDetails[] = SalonCategory::with('duration')->where('id', $c->subcategory_id)->first();
// }
// dd($cartDetails);
$basket = SalonCart::where('user_id', Auth::user()->id)->with('salon','treatment','duration', 'therapist')->get();
// dd($basket);
$salon_therapist = Session::get('selected_salon_therapist') ? User::where('id',Session::get('selected_salon_therapist'))->first() : null;
$salon_booking_date = Session::get('salon_booking_date');
$salon_booking_time = Session::get('salon_booking_time');
$this->data = [
'meta_title' => 'Checkout',
'meta_description' => '',
'meta_keywords' => '',
'basket' => $basket,
'user' => \Auth::user(),
'salon_booking_date' => $salon_booking_date,
'salon_booking_time' => $salon_booking_time,
'cartCount' => $cartCount,
'cartContent' => $cartDetails,
'salon_therapist' =>$salon_therapist
];
// dd($basket);
// dd($this->data);
// dd($this->data);
//render page
return view('schedules::frontend_new.basket.saloncheckout',$this->data);
// return view('schedules::frontend_new.basket.saloncheckout');
}
public function salonCheckoutPay()
{
$booking = Session::get('booking');
if(!isset($booking['address'])){
return redirect('/')->withErrors(['msg' => 'Please enter your postal code/address']);
}
if(Auth::user()) {
$cartCount = SalonCart::where('user_id', Auth::user()->id)->count();
$cartDetails = $this->cartContent();
} else {
return redirect('/');
}
// $cartCount = SalonCart::where('user_id', Auth::user()->id)->count();
// if($cartCount <= 0){
// return redirect('/booking/salon/users');
// }
// $cart = SalonCart::where('user_id', Auth::user()->id)->get();
// $cartDetails = [];
// foreach($cart as $c){
// $cartDetails[] = SalonCategory::with('duration')->where('id', $c->subcategory_id)->first();
// }
$cartContent = $cartDetails;
$cartDetails = [];
$cart = SalonCart::where('user_id', Auth::user()->id)->get();
// dd($cart);
$total_duration = 0;
$total = 0;
foreach($cart as $key => $c){
$cartDetails[] = SalonCategory::with('duration')->where('id', $c->subcategory_id)->first();
$total += $cartDetails[$key]->duration->discounted_price;
$total_duration += $cartDetails[$key]->duration->duration;
}
// dd($cartDetails);
$basket = SalonCart::where('user_id', Auth::user()->id)->with('salon','treatment','duration', 'therapist')->get();
$salon_therapist = Session::get('selected_salon_therapist') ? User::where('id',Session::get('selected_salon_therapist'))->first() : null;
$salon_booking_date = Session::get('salon_booking_date');
$salon_booking_time = Session::get('salon_booking_time');
$this->data = [
'meta_title' => 'Checkout and Pay',
'meta_description' => '',
'meta_keywords' => '',
'basket' => $basket,
'user' => \Auth::user(),
'salon_booking_date' => $salon_booking_date,
'salon_booking_time' => $salon_booking_time,
'cartCount' => $cartCount,
'cartContent' => $cartContent,
'salon_therapist' =>$salon_therapist,
'min_ttl' => null,
'pay_with_voucher'=>false,
'payment_method_restrict_to_cash' => true,
'total_price' => $total,
'total_duration' => $total_duration,
];
//create data array
// $this->data = [
// 'meta_title' => 'Checkout and Pay',
// 'meta_description' => '',
// 'meta_keywords' => '',
// // 'basket' => \Cart::getContent()->sortBy('id'),
// 'user' => \Auth::user(),
// 'payment_method_restrict_to_cash' => true,
// 'min_ttl' => null,
// 'pay_with_voucher'=>false,
// 'cartCount' => $cartCount,
// 'cartContent' => $cartContent,
// ];
// dd($this->data);
//render page
return view('schedules::frontend_new.basket.saloncheckoutpay',$this->data);
}
public function salon_pay_with_cash(Request $request)
{
if(!Auth::user()) {
return redirect('/');
}
$booking = Session::get('booking');
if(!isset($booking['address'])){
return redirect('/')->withErrors(['msg' => 'Please enter your postal code/address']);
}
//therapist key through session
$salon_thid = Session::get('selected_salon_therapist');
// dd($salon_thid);
//date & time through session
$date = Session::get('salon_booking_date');
$time = Session::get('salon_booking_time');
// dd($salon_thid === '');
// dd($salon_thid, $date, $time);
if($salon_thid === '' || $salon_thid === null || !$date || !$time){
return redirect()->back();
}
$booking_date = Carbon::createFromFormat('d-m-Y', $date)->format('Y-m-d');
$total = $total_duration = 0;
$cartCount = SalonCart::where('user_id', Auth::user()->id)->count();
$cart = SalonCart::where('user_id', Auth::user()->id)->with('salon','treatment','duration')->get();
//salon
$salon = User::where('id', $cart[0]->salon_id)->with('salongallaryall','profile','address','workingdays')->first();
// salon therapists
$salon_therapist = User::query()->where('salon_id',$salon->id)->whereHas('roles', function ($query) {
return $query->where('slug', 'therapist');
})->orderBy('nr_crt', 'asc')->get();
// dd($salon_therapist);
foreach($salon_therapist as $key => $therapist){
if($therapist->id == $salon_thid){
$thid = $therapist->id;
// dd($thid);
}
}
// dd("hre");
// salon address with geolocation
if(count($salon->address) != 0){
foreach($salon->address as $address){
if($address->is_main){
$add = $address->address.' '.$address->county.' '.$address->postcode;
}
}
// $add = "Gielly Green Boutique Salon, 42-44 George St, London W1U 7ES, UK";
//Formatted address
$formattedAddr = str_replace(' ','+',$add);
// dd($formattedAddr);
//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);
// dd($output);
if(!empty($output)){
$addressComponents = $output->results[0]->address_components;
foreach($addressComponents as $addrComp){
if($addrComp->types[0] == 'postal_code'){
//Return the zipcode
$address_postcode = $addrComp->long_name;
$booking['postcode'] = $address_postcode;
}
}
}
$salon_geo_location = json_encode($output->results[0]->geometry->location);
$addr_latitude = !empty($output->results[0]->geometry->location->lat)?$output->results[0]->geometry->location->lat:'';
$addr_longitude = !empty($output->results[0]->geometry->location->lng)?$output->results[0]->geometry->location->lng:'';
$this->data['lon'] = $addr_longitude;
$this->data['lat'] = $addr_latitude;
}
//get cart details
$cartDetails = [];
foreach($cart as $key => $c){
$cartDetails[] = SalonCategory::with('duration')->where('id', $c->subcategory_id)->first();
$total += $cartDetails[$key]->duration->discounted_price;
$total_duration += $cartDetails[$key]->duration->duration;
}
if(Auth::user()) {
$cartDetails = $this->cartContent();
}
$cartContent = $cartDetails;
if ($cartCount <= 0){
flash('Your basket is empty. The therapists reservations has overdue.','danger');
return redirect('/');
} //endif
//register payment
DB::beginTransaction();
//Create order
$dataOrder = [
'user_id' => \Auth::user()->id,
'amount' => $total,
'type' => 'cash',
];
$order = Order::create($dataOrder);
// Voucher
// $voucherRepo = new VoucherRepository();
// dd($salon->id);
//create booking orders
$bookingOrders = [];
foreach($cart as $key=>$c) {
$item = SalonCart::with('salon', 'treatment', 'duration', 'therapist')->where('id', $c->id)->first();
$data = [
'order_id' => $order->id,
'user_id' => \Auth::user()->id,
'salon_id' => $item->salon->id,
'is_active' => true,
'amount' => $item->duration->discounted_price,
'date' => $item->booking_date,
'hour' => $item->booking_time,
'duration' => $item->duration->duration,
'duration_min' => $item->duration->duration,
'massage_type' => null,
'address' => $add,
'location' => $add,
'locationGeo' => $salon_geo_location,
'orderInfo' => json_encode($item),
'updatedby_id' => \Auth::user()->id,
];
//save booking order
$bookorder = BookingOrder::create($data);
//attach therapists to booking order
$bookorder->therapists()->attach($item->therapists_id,[
'date'=>$item->booking_date,
'duration'=>$item->duration->duration,
'hour'=>$item->booking_time
]);
//if voucher code was used, mark it as used
// if ($item->attributes->has_voucher){
// $voucherRepo->mark_as_used($item->attributes->voucher['code'],$item->getPriceSum(),$item->id);
// }
//end
$bookingOrders[] = $bookorder;
//end
}
//add mobile notifications
foreach($bookingOrders as $bo){
$notif_message = trans("schedules::booking.mobile_new_order",['number'=>$bo->id,'date'=>$bo->date_to_human,'hour'=>$bo->hour_to_human]);
$notif_users[] = $bo->user_id;
$boInfo = json_decode($bo->orderInfo,true);
$boTherapistsIds[] = $salon->id;
foreach($boTherapistsIds as $thid)
$notif_users[] = $thid;
// dd($notif_users);
//store notifications
foreach($notif_users as $user)
NotifRepository::add($user,$notif_message, 'booking', 'New Booking');
} //endforeach
// //delete session tables: voucher and therapist
// $session_id = $request->session()->getId();
// $sesTh = BasketTherapist::where('session_id',$session_id)->get();
// if ($sesTh){
// foreach($sesTh as $sth)
// $sth->delete();
// }
// //endif
// $sesCodes = BasketVoucher::where('session_id',$session_id)->get();
// if ($sesCodes){
// foreach($sesCodes as $scode)
// $scode->delete();
// }
// //endif
//start a new thread message
$this->book->create_thread($bookorder);
// dd($order);
//commit transaction order details
if ($order){
DB::commit();
//clear cart contents
foreach($cart as $c){
$c->delete();
}
//unset session booking key
//$request->session()->forget('booking');
// clear session
Session::put('salon_booking_date','');
Session::put('salon_booking_time','');
Session::put('selected_salon_therapist','');
//send email
$this->sendSalonEmailCheckout($bookingOrders);
}
else{
DB::rollBack();
}
//redirect to success page
return redirect(route('bookings.basket.paysuccess'));
}
public function cartContent(){
if(!Auth::user()){
$cartDetails = [];
return $cartDetails;
}
$cart = SalonCart::where('user_id', Auth::user()->id)->get();
$cartDetails = [];
foreach($cart as $c){
$get_date = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s',$c->created_at)->addMinutes(15)->format('Y-m-d H:i:s');
$reserved_until = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s',$get_date);
$reserved_ttl = $reserved_until->diffInSeconds(null,false);
$reserved_ttl = \Carbon\Carbon::now()->diffInSeconds($reserved_until,false);
if ($reserved_ttl<=0){
SalonCart::where('id', $c->id)->delete();
return;
}
$details = SalonCategory::with('duration')->where('id', $c->subcategory_id)->first();
$details->setAttribute('cart_id', $c->id);
$parentCategory = SalonCategory::where('id', $details->parent_category_id)->first();
$parentCategory1 = SalonCategory::where('id', $parentCategory->parent_category_id)->first();
$parentCategory2 = SalonCategory::where('id', $parentCategory1->parent_category_id)->first();
if(empty($parentCategory1->image)){
$parentCategory2 = SalonCategory::where('id', $parentCategory1->parent_category_id)->first();
$details->setAttribute('parent_image', $parentCategory2->image);
$details->setAttribute('parent_icon', $parentCategory2->icon);
} else {
$details->setAttribute('parent_image', $parentCategory1->image);
$details->setAttribute('parent_icon', $parentCategory1->icon);
}
$cartDetails[] = $details;
}
return $cartDetails;
}
}