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\CheckExtensionBasketEvent;
use App\Http\Controllers\ApiController;
use App\Modules\Banners\Repositories\BannersRepo;
use App\Modules\Invoices\Models\Invoice_item;
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 Cmgmyr\Messenger\Models\Thread;
use Darryldecode\Cart\Cart;
use Darryldecode\Cart\CartCondition;
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 ApiBasketExtensionController 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;
}
/**
* Extend Booking
* @param $id
*/
public function action_extend($id, Request $request)
{
$booking = BookingOrder::find($id);
$user = $this->user;
//return empty object if booking is not found
if (!$booking)
return response([
'success'=>false,
'message'=>'The Booking is not found.',
],200);
$service = ServiceDuration::find($request->extensionId);
$total = $service->price;
if (!$booking)
return response([
'success'=>false,
'message'=>'The Extension Option is available anymore.',
],200);
//refund booking value
$repo = new BookingRepository();
$can_extend = $repo->can_extend_with($booking,$service);
if (!$can_extend)
return response([
'success'=>false,
'message'=> trans('schedules::booking.message_error_extension_overlap'),
],200);
//first add to basket
$infoBooking = json_decode($booking->orderInfo,true);
//make payment
if ($booking->card_trans_id)
{
//pay with existing card
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);
} // try/catch
$status = $this->registerpayment($booking,$service);
if ($status)
$message = 'Your booking has been successfully extended.';
else
$message = trans('schedules::booking.message_error_extension_overlap');
}
else{
//pay by cash
$status = $this->registerpayment($booking,$service);
if ($status)
$message = 'Your booking has been successfully extended.';
else
$message = trans('schedules::booking.message_error_extension_overlap');
} //end elseif
//return response
return response([
'success'=>$status,
'message'=>$message
],200);
}
/**
* Register booking extension and update booking data
* @param $booking
* @param $service
*/
protected function registerpayment($booking,$service)
{
//start transaction
DB::beginTransaction();
$bookingTherapist = null;
if($booking->therapists)
{
$bookingTherapist = $booking->therapists->first();
}
if($bookingTherapist && $bookingTherapist->services_commisions)
{
if(isset($bookingTherapist->services_commisions[$service->id]))
{
$commision_co = $bookingTherapist->services_commisions[$service->id]['commision_co'];
$commision_th = $bookingTherapist->services_commisions[$service->id]['commision_th'];
}
else
{
$commision_co = $service->commision_co;
$commision_th = $service->commision_th;
}
}
else
{
$commision_co = $service->commision_co;
$commision_th = $service->commision_th;
}
$allInfo = json_decode($booking->orderInfo,true);
$allInfo['has_extension'] = true;
$allInfo['extension'][] = [
'duration_id' => $service->id,
'duration' => $service->name,
'duration_min' => $service->duration,
'duration_commision' => [
'company' => $commision_co,
'therapist' => $commision_th,
],
'price' => $service->price,
'date' => Carbon::now()->format('Y-m-d H:i:s'),
];
//thread message
$subject = $booking->treadsubject;
$thread = Thread::where('subject',$subject)->first();
//create order bookings array
$data = [
'amount' => $booking->amount+$service->price,
'duration' => $booking->duration.' + extension: '.$service->name,
'duration_min' => $booking->duration_min+$service->duration,
'orderInfo' => json_encode($allInfo),
'updatedby_id' => $this->user->id,
];
//save booking order
$booking->update($data);
//update thread subject
$thread->subject = $booking->treadsubject;
$thread->save();
//if booking has client invoice
if ($booking->invoice){
//update invoice total
$invoice = $booking->invoice;
$invoice->amount_net = $invoice->amount_net+$service->price;
$invoice->amount = $invoice->amount+$service->price;
$invoice->save();
//add new invoice item
$extensionItem = [
'invoice_id'=>$invoice->id,
'qty'=>1,
'name'=> 'Extension ',
'notes' => "of ".$service->name,
'um'=>'pcs',
'unit_price' => $service->price,
'amount_net' => $service->price,
'amount' => $service->price,
'tax_name' => '',
'tax_value' => 0,
];
Invoice_item::create($extensionItem);
} //end invoice
//update therapists to booking order
foreach($booking->therapists as $therapist){
$thID = $therapist->id;
$booking->therapists()->updateExistingPivot($thID,['duration'=>($therapist->pivot->duration+$service->duration)]);
} //endforeach
$bookingOrders[] = $booking;
//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', 'Booking Updated');
} //endforeach
if ($booking){
DB::commit();
//send email
$this->sendEmailCheckout($bookingOrders);
return true;
}
else{
DB::rollBack();
return false;
}
}
/**
* Pay with existing card
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function pay_with_existing_card(Request $request)
{
//card restriction
return response([
'success'=>false,
'message' => trans('schedules::payment.message_card_restriction'),
],403);
//get current user
$user = User::find($this->user->id);
if (!$user->braintree_id){
return response([
'success'=>false,
'message'=>'You have no valid card defined. Please enter one!',
],200);
} //end
//get total amount
$cart = app('cart_extension');
$total = round($cart->getTotal(),2);
//charge user amount
try {
$name = "massage services";
$response = $user->invoiceFor($name,$total);
} catch (\Exception $e) {
return response([
'success'=>false,
'message'=>$e->getMessage(),
],200);
}
//register payment
$this->register_payment($response,$request);
//redirect to success page
return $booking;
}
/**
* Pay with existing card
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function pay_with_cash(Request $request)
{
$cart = app('cart_extension');
if ($cart->isEmpty()){
flash('The time for your booking extension has expired.','danger');
return redirect()->route('account.profile.mybookings');
} //endif
//get current user
$user = User::find(Auth::user()->id);
//get total amount
$total = round($cart->getTotal(),2);
//register payment
DB::beginTransaction();
//create booking orders
$bookingOrders = [];
foreach($cart->getContent()as $item){
$booking = $item->attributes->booking_obj;
$bookingTherapist = null;
if($booking->therapists)
{
$bookingTherapist = $booking->therapists->first();
}
if($bookingTherapist && $bookingTherapist->services_commisions)
{
if(isset($bookingTherapist->services_commisions[$item->attributes->duration_id]))
{
$commision_co = $bookingTherapist->services_commisions[$item->attributes->duration_id]['commision_co'];
$commision_th = $bookingTherapist->services_commisions[$item->attributes->duration_id]['commision_th'];
}
else
{
$commision_co = $item->attributes->duration_commision['company'];
$commision_th = $item->attributes->duration_commision['therapist'];
}
}
else
{
$commision_co = $item->attributes->duration_commision['company'];
$commision_th = $item->attributes->duration_commision['therapist'];
}
$allInfo = json_decode($booking->orderInfo,true);
$allInfo['has_extension'] = true;
$allInfo['extension'] = [
'duration_id' => $item->attributes->duration_id,
'duration' => $item->name,
'duration_min' => $item->attributes->duration_min,
'duration_commision' => [
'company' => $commision_co,
'therapist' => $commision_th,
],
'price' => $item->getPriceSumWithConditions(),
'date' => Carbon::now()->format('Y-m-d H:i:s'),
];
//create order bookings array
$data = [
'amount' => $booking->amount+$item->getPriceSumWithConditions(),
'duration' => $booking->duration.' + extension: '.$item->name,
'duration_min' => $booking->duration_min+$item->attributes->duration_min,
'orderInfo' => json_encode($allInfo),
'updatedby_id' => \Auth::user()->id,
];
//save booking order
$booking->update($data);
//update therapists to booking order
foreach($booking->therapists as $therapist){
$thID = $therapist->id;
$booking->therapists()->updateExistingPivot($thID,['duration'=>($therapist->pivot->duration+$item->attributes->duration_min)]);
} //endforeach
$bookingOrders[] = $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
//commit transaction order details
if ($booking){
DB::commit();
//clear cart contents
$cart->clear();
//send email
$this->sendEmailCheckout($bookingOrders);
}
else{
DB::rollBack();
}
//redirect to success page
return redirect(route('bookings.extension.paysuccess'));
}
/**
* Register payment
* @param $response
*/
protected function register_payment($response,Request $request)
{
$cart = app('cart_extension');
DB::beginTransaction();
//create booking orders
$bookingOrders = [];
foreach($cart->getContent()as $item){
$booking = $item->attributes->booking_obj;
$bookingTherapist = null;
if($booking->therapists)
{
$bookingTherapist = $booking->therapists->first();
}
if($bookingTherapist && $bookingTherapist->services_commisions)
{
if(isset($bookingTherapist->services_commisions[$item->attributes->duration_id]))
{
$commision_co = $bookingTherapist->services_commisions[$item->attributes->duration_id]['commision_co'];
$commision_th = $bookingTherapist->services_commisions[$item->attributes->duration_id]['commision_th'];
}
else
{
$commision_co = $item->attributes->duration_commision['company'];
$commision_th = $item->attributes->duration_commision['therapist'];
}
}
else
{
$commision_co = $item->attributes->duration_commision['company'];
$commision_th = $item->attributes->duration_commision['therapist'];
}
$allInfo = json_decode($booking->orderInfo,true);
$allInfo['has_extension'] = true;
$allInfo['extension'][] = [
'duration_id' => $item->attributes->duration_id,
'duration' => $item->name,
'duration_min' => $item->attributes->duration_min,
'duration_commision' => [
'company' => $commision_co,
'therapist' => $commision_th,
],
'price' => $item->getPriceSumWithConditions(),
'date' => Carbon::now()->format('Y-m-d H:i:s'),
];
//create order bookings array
$data = [
'amount' => $booking->amount+$item->getPriceSumWithConditions(),
'duration' => $booking->duration.' + extension: '.$item->name,
'duration_min' => $booking->duration_min+$item->attributes->duration_min,
'orderInfo' => json_encode($allInfo),
'updatedby_id' => \Auth::user()->id,
];
//save booking order
$booking->update($data);
//if booking has client invoice
if ($booking->invoice){
//update invoice total
$invoice = $booking->invoice;
$invoice->amount_net = $invoice->amount_net+$item->getPriceSumWithConditions();
$invoice->amount = $invoice->amount+$item->getPriceSumWithConditions();
$invoice->save();
//add new invoice item
$extensionItem = [
'invoice_id'=>$invoice->id,
'qty'=>1,
'name'=> 'Extension ',
'notes' => "of ".$item->name,
'um'=>'pcs',
'unit_price' => $item->getPriceSumWithConditions(),
'amount_net' => $item->getPriceSumWithConditions(),
'amount' => $item->getPriceSumWithConditions(),
'tax_name' => '',
'tax_value' => 0,
];
Invoice_item::create($extensionItem);
}
//update therapists to booking order
foreach($booking->therapists as $therapist){
$thID = $therapist->id;
$booking->therapists()->updateExistingPivot($thID,['duration'=>($therapist->pivot->duration+$item->attributes->duration_min)]);
} //endforeach
$bookingOrders[] = $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
//commit transaction order details
if ($booking){
DB::commit();
//clear cart contents
$cart->clear();
//send email
$this->sendEmailCheckout($bookingOrders);
}
else{
DB::rollBack();
}
}
/**
* Send condfirmation order
* @param $order
*/
public function sendEmailCheckout($orders)
{
$order = $orders[0];
$user = User::findOrFail($order->user_id);
$data['user'] = $user;
$data['order'] = $order;
//send confirmation email
Mail::send('schedules::frontend.emails.extendorder', ['user' => $user, 'order'=>$order], 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').' – extension booking confirmation');
});
//send therapist email confirmation
$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_extendorder', ['user' => $therapist, 'order'=>$order], 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').' – extension booking confirmation');
});
} //end foreach
}
}