Server : Apache System : Linux 145.162.205.92.host.secureserver.net 5.14.0-611.45.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Apr 1 05:56:53 EDT 2026 x86_64 User : tradze ( 1001) PHP Version : 8.1.34 Disable Function : NONE Directory : /home/tradze/www/app/Modules/Users/Http/Controllers/Api/ |
<?php
namespace App\Modules\Users\Http\Controllers\Api;
use App\Events\ApiOverdueBasketEvent;
use App\Events\CheckExtensionBasketEvent;
use App\Http\Controllers\ApiController;
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\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\BookingRepository;
use App\Modules\Services\Models\FocalPoint;
use App\Modules\Services\Models\ServiceDuration;
use App\Modules\Services\Models\ServiceType;
use App\Modules\Postcodes\Models\Postcode;
use App\Modules\Vouchers\Repositories\VoucherRepository;
use App\User;
use Carbon\Carbon;
use Darryldecode\Cart\Cart;
use Darryldecode\Cart\CartCondition;
use Illuminate\Console\Scheduling\Event;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Mail;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\Request;
use Laracasts\Flash\Flash;
use Mockery\CountValidator\Exception;
class ApiBasketNowController extends ApiController
{
/**
* 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, BookingRepository $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;
}
/**
* Add items in basket
* @param int $checkout
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
*/
public function add(Request $request, $checkout=0)
{
//first clear basket session tables for overdue items
\Event::fire(new ApiOverdueBasketEvent());
//get booking data from session
$booking = Session::get('booking');
$booking['postcode'] = $request->postcode;
$booking['address'] = $request->address;
$booking['date'] = $request->date;
$booking['hour'] = $request->hour;
$booking['massage'] = $request->massage;
$booking['duration'] = $request->duration;
$booking['therapists_opt'] = $request->therapists_opt;
$booking['selected_therapists'] = $request->selected_therapists;
\Cart::clear();
BasketVoucher::where('session_id',request()->session()->getId())->delete();
BasketTherapist::where('session_id',request()->session()->getId())->delete();
$therapists=1;
$type='1 therapist';
switch ($request->therapists_opt){
case '1_th':
$therapists=1;
$type='1 therapist';
break;
case '2_th':
$therapists=2;
$type='2 therapists';
break;
case '4hands':
$therapists=2;
$type='four hands massage';
break;
} //end switch
$booking['therapists_opt'] = $request->therapists_opt;
$booking['therapists'] = $therapists;
$booking['type'] = $type;
unset($booking['selected_therapists']);
if (count($request->selected_therapists)){
foreach($request->selected_therapists as $th){
if (is_array($th))
$booking['selected_therapists'][] = $th['id'];
else
$booking['selected_therapists'][] = $th;
} //endoreach
}
// $booking['selected_therapists'] = $request->selected_therapists;
Session::put('booking',$booking);
$mandatory_fields = ['postcode','duration','massage','date', 'hour', 'selected_therapists'];
foreach($mandatory_fields as $field){
if (!isset($booking[$field])){
return response([$booking,$field],200);
//return booking data
return response([
'success'=>false,
'message'=>'You must select the postcode, massage duration, type of massage, date of massage, desired hour and the therapist',
'booking'=>$booking,
],200);
}
} //endforeach
// //testing
// return response([
// 'success'=>false,
// 'message'=>'sunt aici',
// 'items'=>[],
// 'booking'=>$booking,
// ],200);
//add to basket
switch ($booking['therapists_opt']){
case '2_th':{
$this->add_therapists($booking);
break;
}
case '4hands':{
$this->add_4hands($booking);
break;
}
default:{
$test = $this->add_single($booking);
break;
}
} //end switch
$items = \Cart::getContent();
foreach($items as $item){
$data[] = [
'id'=>$item->id,
'price'=>$item->getPriceSum(),
'total'=>$item->getPriceSumWithConditions(),
'reserved_until'=>$item->attributes['reserved_until'],
'can_order_table'=>$item->attributes['can_order_table'],
'has_table'=>$item->attributes['has_table'],
'table_price' => env('TABLE_VALUE',9.99),
'disclaimer' => (!$item->attributes['can_order_table'])?'can be delivered only over 24h notice!':'',
'has_transport' => $item->attributes['has_transport'],
'transport_cost' => $item->attributes['transport_cost'],
];
} //endforeach
//return booking session data
return response([
'success'=>true,
'message'=>null,
'items'=>$data,
'total'=>\Cart::getTotal(),
'session'=> $request->session()->getId(),
],200);
}
/**
* Add item in basket for single massage option
* @param $booking
*/
protected function add_single($booking)
{
$therapists = $this->book->selected_therapists();
// $therapists = User::whereIn('id',$booking['selected_therapists'])->get();
$duration = ServiceDuration::where('id',$booking['duration'])->first();
$massage_type = ServiceType::where('id',$booking['massage'])->first();
$client = User::find($this->user->id);
$quantity = $booking['therapists'];
$price = $duration->price;
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){
$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' => $client->name?$client->name:'',
'user_phone' => $client->profile->mobile_number?$client->profile->mobile_number:'',
'address' => $booking['address'],
'postcode' => $booking['postcode'],
'county' => 'London',
'location' => $googlePlaces['formatted_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' => $client->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);
} //endforeach
//unset session booking
// Session::forget('booking');
}
/**
* Add items in basket for 2 therapists massage option
* @param $booking
*/
protected function add_therapists($booking)
{
return $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);
$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' => $duration->commision_co,
'therapist' => $duration->commision_th,
],
'massage_type' => $massage_type->name,
'massage_type_id' => $massage_type->id,
'focal_points' => $focal_points_string,
'has_table' => false,
'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);
} //endforeach
//unset session booking
Session::forget('booking');
}
/**
* 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');
}
/**
* 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
$client = User::find($booking->user_id);
//the booking must be owned by
if (!$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' => $client->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);
}
/**
* 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;
}
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;
$transportCost = TransportCost::where('from_id',$district->id)
->where('to_id',$postcode_district->id)
->first();
$cost += $transportCost->price;
} //endforeach
//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);
}
/**
* 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);
}
/**
* 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)
{
$productID = $request->cartId;
$table_value = 9.99;
return response([
'success'=>false,
'message'=> 'Unfortunately we do not deliver tables to your location at this time!',
'data' => [],
],200);
//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'=> 'Unfortunately we do not deliver tables to your location at this time!',
'data' => [],
],200);
}
//cannot order table only over 24h
if (!$check->attributes->can_order_table){
return response([
'success'=>false,
'message'=>'can be delivered only over 24h notice!',
'data'=>[],
],200);
} //endif
if ($check->attributes->has_table){
return response([
'success'=>false,
'message'=>'Table has been already added!',
'data' => [
'has_table'=>true,
'total'=>$check->getPriceSumWithConditions(),
],
],200);
}
$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,
'message'=>null,
'data'=>[
'has_table'=>$attributes['has_table'],
'total' => $item->getPriceSumWithConditions()
]
];
//return response
return response($message,200);
}
/**
* Remove table condition
* @param Request $request
*/
public function remove_table(Request $request)
{
$productID = $request->cartId;
//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,
'data'=>[
'has_table'=>$attributes['has_table'],
'total'=>$item->getPriceSumWithConditions(),
]
];
//return response
return response($message,200);
}
/**
* Add table condition
* @param Request $request
*/
public function add_voucher(Request $request)
{
// return response([
// 'success'=>false,
// 'message'=>"Oops, something went wrong! Please try again.",
// 'data'=> \Cart::getContent(),
// 'session'=> $request->session()->getId(),
// ],200);
$productID = $request->cartId;
//get item cart
$item = \Cart::get($productID);
if (!$item){
return response([
'success'=>false,
'message'=>"Oops, something went wrong! Please try again.",
'data'=>\Cart::getContent(),
],200);
}
$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!",
'data'=>[],
],200);
//get voucher code
$checkVoucher = new VoucherRepository();
$voucher = $checkVoucher->validate_voucher($request->value,$productID,$this->user);
//if voucher is not valid, return response with message
if (!$voucher['valid'])
return response([
'success'=>false,
'message'=>$voucher['message'],
'data'=>[],
],200);
//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,
));
//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);
//return response
$message = [
'success'=>true,
'data'=>[
'discount'=>(-$condValue),
'total'=>$item->getPriceSumWithConditions(),
],
'cart'=> \Cart::getContent(),
'session'=> $request->session()->getId(),
];
//return response
return response($message,200);
}
/**
* Remove table condition
* @param Request $request
*/
public function remove_voucher(Request $request)
{
$productID = $request->cartId;
//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,
'data'=>[
'total'=>$item->getPriceSumWithConditions(),
]
];
//return response
return response($message,200);
}
/**
* Pay method
* @param Request $request
*/
public function pay(Request $request)
{
if (\Cart::isEmpty()){
return response([
'success'=>false,
'message' => 'Time\'s up. The therapists reservations has overdue.',
],200);
} //endif
$total = \Cart::getTotal();
$user = User::find($request->client_id);
$token = $request->input('payment-method-nonce');
//if user has no plans, create one
if (!$user->braintree_id){
$user->newSubscription('single-charge', 'qrjb')->create($token,[
'email'=>$user->email,
'phone'=>$user->profile->mobile_phone,
]);
}
else{
//update token for each payment
try{
$user->updateCard($token);
}
catch (\Exception $e){
$message = $e->getMessage();
$message = str_ireplace('braintree','Tradze',$message);
return response([
'success'=>false,
'message'=>$message,
],200);
}
}
//change user amount
try {
$name = "massage services";
$response = $user->invoiceFor($name,$total);
} catch (\Exception $e) {
$message = $e->getMessage();
$message = str_ireplace('braintree','Tradze',$message);
return response([
'success'=>false,
'message'=>$message,
],200);
}
//register payment
$this->register_payment($response,$request);
//redirect to success page
return response([
'success'=>true,
'message'=>'YOUR ORDER IS CONFIRMED',
'card_info' => [
'payment_id' => $user->braintree_id,
'paypal_email' => $user->paypal_email,
'card_brand' => $user->card_brand,
'card_last_four' => $user->card_last_four,
'expiry'=>$response->transaction->creditCardDetails->expirationDate,
],
],200);
}
/**
* Pay with existing card
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function pay_with_existing_card(Request $request)
{
if (\Cart::isEmpty()){
return response([
'success'=>false,
'message' => 'Time\'s up. The therapists reservations has overdue.',
],403);
} //endif
//get current user
$user = User::find($request->client_id);
if (!$user->braintree_id){
return response([
'success'=>false,
'message'=>'You have no valid card defined. Please enter one!',
],200);
} //end
// return response([
// 'success'=>false,
// 'message'=>'You have no valid card defined. Please enter one!',
// ],200);
//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','Tradze',$message);
return response([
'success'=>false,
'message'=>$message,
],200);
}
//register payment
$this->register_payment($response,$request);
//redirect to success page
return response([
'success'=>true,
'message'=>'YOUR ORDER IS CONFIRMED',
],200);
}
/**
* Pay with existing card
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function pay_with_cash(Request $request)
{
if (\Cart::isEmpty()){
return response([
'success'=>false,
'message' => 'Time\'s up. The therapists reservations has overdue.',
],403);
} //endif
//get current user
$user = User::find($this->user->id);
//get total amount
$total = \Cart::getTotal();
//register payment
DB::beginTransaction();
//Create order
$dataOrder = [
'user_id' => $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' => $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?$item->attributes->address:'no address',
'location' => $item->attributes->location?$item->attributes->location:'location not found',
'locationGeo' => json_encode($item->attributes->locationGeo),
'orderInfo' => json_encode($allInfo),
'updatedby_id' => $this->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
//start a new thread message
$this->book->create_thread($bookorder);
$bookingOrders[] = $bookorder;
} //endforeach
//add mobile notifications
foreach($bookingOrders as $bo){
$notif_message = trans("schedules::booking.mobile_update_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
//
//
// return response([
// 'success'=>false,
// 'message' => 'Final',
// 'order' => $bookorder,
//
// ],200);
//commit transaction order details
if ($order){
DB::commit();
//clear cart contents
\Cart::clear();
//unset session booking key
$request->session()->forget('booking');
//send email
$this->sendEmailCheckout($bookingOrders);
}
else{
DB::rollBack();
return response([
'success'=>false,
'message' => 'Something went wrong. Please try again!',
],403);
}
//return success response
return response([
'success'=>true,
'message' => 'Your appointment has been successfully registered',
],200);
}
/**
* Register payment
* @param $response
*/
protected function register_payment($response,Request $request)
{
DB::beginTransaction();
$user = User::find($this->user->id);
//Create order
$dataOrder = [
'user_id' => $user->id,
'amount' => \Cart::getTotal(),
'type' => 'card',
'card_trans_id' => $response->transaction->id,
'card_trans_status' => (bool)$response->success,
'card_details' => json_encode([
'customerLocation' => $response->transaction->creditCardDetails->customerLocation,
'cardType' => $response->transaction->creditCardDetails->cardType,
'expirationDate' => $response->transaction->creditCardDetails->expirationDate,
'imageUrl' => $response->transaction->creditCardDetails->imageUrl,
'maskedNumber' => $response->transaction->creditCardDetails->maskedNumber,
'last4' => $response->transaction->creditCardDetails->last4,
'bin' => $response->transaction->creditCardDetails->bin,
]),
];
$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' => $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!=null)?$item->attributes->address:'no address',
'location' => $item->attributes->location,
'locationGeo' => json_encode($item->attributes->locationGeo),
'orderInfo' => json_encode($allInfo),
'card_trans_id' => $response->transaction->id,
'card_trans_status' => (bool)$response->success,
'card_details' => json_encode([
'customerLocation' => $response->transaction->creditCardDetails->customerLocation,
'cardType' => $response->transaction->creditCardDetails->cardType,
'expirationDate' => $response->transaction->creditCardDetails->expirationDate,
'imageUrl' => $response->transaction->creditCardDetails->imageUrl,
'maskedNumber' => $response->transaction->creditCardDetails->maskedNumber,
'last4' => $response->transaction->creditCardDetails->last4,
'bin' => $response->transaction->creditCardDetails->bin,
]),
'updatedby_id' => $this->user->id,
];
//save booking order
$bookorder = BookingOrder::create($data);
//add mobile notifications
foreach($bookingOrders as $bo){
$notif_message = trans("schedules::booking.mobile_update_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
//create invoice
if ($response->transaction->id){
$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
$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
//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');
//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;
//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('Tradze Massage website – booking confirmation');
});
}
}