Sh3ll
OdayForums


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/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/tradze/public_html/app/Modules/Schedules/Http/Controllers/Frontend/BasketController.php
<?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'=>"&#8356; ".$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'=>"&#8356; ".$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'=>"&#8356; ".$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'=>"&#8356; ".$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'=>"&#8356; ".$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;    
    }

}

ZeroDay Forums Mini