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/Admin/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/tradze/public_html/app/Modules/Schedules/Http/Controllers/Admin/BookingsController.php
<?php

namespace App\Modules\Schedules\Http\Controllers\Admin;

use App\Http\Controllers\AdminController;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Modules\Invoices\Repositories\BookingInvoiceRepository;
use App\Modules\Schedules\Http\Requests\BookingUpdateRequest;
use App\Modules\Schedules\Models\BookingOrder;
use App\Modules\Schedules\Models\BookingInternalNote;
use App\Modules\Schedules\Repositories\BookingRepository;
use App\Modules\Schedules\Scopes\ActiveScope;
use App\Modules\Services\Models\ServiceDuration;
use App\Modules\Services\Models\ServiceType;
//use Braintree\Transaction;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Session;
use Laracasts\Flash\Flash;
use App\User;
use Yajra\Datatables\Datatables;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Artisan;

class BookingsController extends AdminController
{

    /**
     * The booking repository instance.
     *
     * @var pageRepository
     */
    protected $repo;

    /**
     * Create a new controller instance.
     *
     * @param  TaskRepository  $tasks
     * @return void
     */
    public function __construct(BookingRepository $repository)
    {
        parent::__construct();

        $this->repo  = $repository;
    }



    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index(Request $request)
    {
        // dd("saivbsa");
        //unset any booking key from session
        $this->repo->unset_booking_data();

        //store filters to sessions
        if ($request->get('search')) {
            $request->session()->put('schedules.bookings.filters', $request->except(['_token', 'search']));
            return redirect(route('admin.schedules.bookings.index'));
        } elseif ($request->get('reset')) {
            $request->session()->forget('schedules.bookings.filters');
            return redirect(route('admin.schedules.bookings.index'));
        }

        //create data array
        $this->data['page_title'] = trans('schedules::booking.page_title');
        $this->data['filters'] = $request->session()->get('schedules.bookings.filters');
        if (Auth::user()->hasRole('salon')) {
            $this->data['search'] = [
                'clients' => ['' => trans('schedules::booking.search_by_client')],
                'therapists' => User::where('salon_id', Auth::user()->id)->pluck('name', 'id')->put('', trans('schedules::booking.search_by_therapist')),
                'salon' => User::ofSalon()->pluck('name', 'id')->put('', trans('schedules::booking.search_by_salon')),
            ];
        } else {
            $this->data['search'] = [
                'clients' => User::ofClients()->pluck('name', 'id')->put('', trans('schedules::booking.search_by_client')),
                'therapists' => User::ofTherapists()->pluck('name', 'id')->put('', trans('schedules::booking.search_by_therapist')),
                'salon' => User::ofSalon()->pluck('name', 'id')->put('', trans('schedules::booking.search_by_salon')),
            ];
        }
        //render page
        return view('schedules::admin.bookings.booking_index', $this->data);
    }

    /**
     * Show a list of all companies
     *
     * @return mixed
     */
    public function data(Request $request)
    {
        //create object contact
        $obj = $this->getData($request);

        //create array with contacts permissions access

        $this->data['can'] = [
            'view'   => $this->data['user']->roles->pluck('slug')[0] == 'developer' || $this->data['user']->roles->pluck('slug')[0] == 'salon',
            'edit'   => $this->data['user']->roles->pluck('slug')[0] == 'developer' || $this->data['user']->roles->pluck('slug')[0] == 'salon',
            'delete' => $this->data['user']->roles->pluck('slug')[0] == 'developer' || $this->data['user']->roles->pluck('slug')[0] == 'salon',
            'create_invoice' => $this->data['user']->roles->pluck('slug')[0] == 'developer' || $this->data['user']->roles->pluck('slug')[0] == 'salon',
        ];

        //return datatables data
        return Datatables::of($obj)
            ->editColumn('internal_notes', function ($o) {
                $this->data['o'] = $o;
                return view('schedules::admin.bookings.partial_booking_internal_notes', $this->data)->render();
            })
            ->addColumn('date_hour', function ($o) {
                return $o->date_to_human . ', ' . $o->hour_to_human;
            })
            ->editColumn('invoice', function ($o) {
                $this->data['invoice'] = $o->invoice;
                return view('schedules::admin.bookings.partial_invoice', $this->data)->render();
            })
            ->addColumn('client', function ($o) {
                if (!$o->user)
                    return '';

                return $o->user->name;
            })
            ->addColumn('therapist', function ($o) {
                $list = [];
                foreach ($o->therapists as $th)
                    $list[] = $th->name;

                return implode(', ', $list);
            })
            ->editColumn('is_active', function ($o) {
                $this->data['o'] = $o;
                return view('schedules::admin.bookings.partial_booking_status', $this->data)->render();
            })
            ->addColumn('actions', function ($o) {
                $this->data['o'] = $o;
                return view('schedules::admin.bookings.booking_list_actions', $this->data)->render();
            })
            ->rawColumns([
                'amount',
                'internal_notes',
                'invoice',
                'is_active',
                'actions'
            ])
            ->make(true);
    }

    public function clearCache()
    {
        if (!Artisan::call('cache:clear')) {
            return 'Cache cleared successfully.';
        } else {
            return 'Cache not cleared.';
        }

        return "nothing";
    }

    /**
     * Get object entries
     * @param Request $request
     */
    protected function getData(Request $request)
    {
        if (Auth::user()->hasRole('salon')) {
            $filters = $request->session()->get('schedules.bookings.filters');

            $obj = BookingOrder::query()
                ->where('salon_id', Auth::user()->id)
                ->OfTherapist(isset($filters['search_therapist']) ? $filters['search_therapist'] : null)
                ->OfClient(isset($filters['search_client']) ? $filters['search_client'] : null)
                ->OfOrder(isset($filters['search_order_number']) ? $filters['search_order_number'] : null)
                ->OfNumber(isset($filters['search_number']) ? $filters['search_number'] : null)
                ->OfDateFrom(isset($filters['search_date_from']) ? $filters['search_date_from'] : null)
                ->OfDateTo(isset($filters['search_date_to']) ? $filters['search_date_to'] : null)
                ->withoutGlobalScope(ActiveScope::class)
                ->orderBy('id', 'desc');
        } else {
            $filters = $request->session()->get('schedules.bookings.filters');
            $obj = BookingOrder::query()
                ->OfTherapist(isset($filters['search_therapist']) ? $filters['search_therapist'] : null)
                ->ofSalon(isset($filters['search_salon']) ? $filters['search_salon'] : null)
                ->OfClient(isset($filters['search_client']) ? $filters['search_client'] : null)
                ->OfOrder(isset($filters['search_order_number']) ? $filters['search_order_number'] : null)
                ->OfNumber(isset($filters['search_number']) ? $filters['search_number'] : null)
                ->OfDateFrom(isset($filters['search_date_from']) ? $filters['search_date_from'] : null)
                ->OfDateTo(isset($filters['search_date_to']) ? $filters['search_date_to'] : null)
                ->withoutGlobalScope(ActiveScope::class)
                ->orderBy('id', 'desc');
        }
        //return object
        return $obj;
    }

    /**
     * Display booking details
     * @param $id
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function show($id)
    {
        //unset any booking key from session
        $this->repo->unset_booking_data();

        $bookings = BookingOrder::where('id', $id)->withoutGlobalScope(ActiveScope::class)->first();
        $bookingRepo = new BookingRepository();
        $card_trans_status = null;
        $refundID = null;
        //        if ($bookings->card_trans_id){
        //            try{
        //                $trans = Transaction::find($bookings->card_trans_id);
        //                $refundID = $trans->refundId;
        //                if (!$refundID)
        //                    $card_trans_status=trans("schedules::booking.text_{$trans->status}");
        //                else
        //                    $card_trans_status=trans("schedules::booking.text_refunded");
        //            }
        //            catch(\Exception $e){
        //
        //            }
        //        } //end booking has been paid with card

        //create data array
        $this->data['page_title'] = trans('schedules::booking.page_title');
        $this->data['booking'] = $bookings;
        $this->data['order_items'] = $bookingRepo->get_order_cart($bookings->cart_trans_id);
        $this->data['info'] = json_decode($bookings->orderInfo, true);
        $this->data['card_trans_status'] = $card_trans_status;
        $this->data['refundID'] = $refundID;
        if ($bookings->salon_id) {
            return view('schedules::admin.bookings.salon_booking_show', $this->data);
        }
        //render page
        return view('schedules::admin.bookings.booking_show', $this->data);
    }

    /**
     * Edit Page
     * @param $id
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
     */
    public function edit($id)
    {
        //get booking
        $booking = BookingOrder::where('id', $id)->withoutGlobalScope(ActiveScope::class)->first();
        // dd($booking);
        if (!$booking) {
            flash('Booking not found!', 'danger');
            return redirect(route('admin.schedules.bookings.index'));
        } //endif

        //can be edited only the future bookings
        //        if (!$booking->time_left_in_seconds){
        //            flash(trans('schedules::booking.message_error_restrict_edit'),'danger');
        //            return redirect(route('admin.schedules.bookings.show',['bookings'=>$booking->id]));
        //        } //endif


        //set booking data
        $this->repo->set_booking_data($booking);
        $booking_info = json_decode($booking->orderInfo, true);

        $hours = $this->get_hours($booking->date->format('Y-m-d'), !empty($booking_info['therapistIds']) ? $booking_info['therapistIds'] : '');

        //create data array
        $this->data['page_title'] = trans('schedules::booking.page_title');
        $this->data['obj'] = $booking;
        $this->data['hours'] = $hours;
        $this->data['info'] = json_decode($booking->orderInfo, true);
        // dd($this->data['info']);
        $this->data['form']['massage_types'] = ServiceType::pluck('name', 'id');
        $this->data['form']['durations'] = ServiceDuration::where('is_extra', 0)->pluck('name', 'id');
        $this->data['form']['therapists'] = User::OfTherapists()->get()->pluck('name', 'id');
        if ($booking->salon_id) {
            return view('schedules::admin.bookings.salon_booking_edit_v2', $this->data);
        }
        //render page
        return view('schedules::admin.bookings.booking_edit_v2', $this->data);
    }

    /**
     * Update
     * @param Request $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function update(BookingUpdateRequest $request, $id)
    {
        if ($request->is_salon) {
            //for Salon
            //get booking
            $booking = BookingOrder::where('id', $id)->withoutGlobalScope(ActiveScope::class)->first();
            $orderInfo = json_decode($booking->orderInfo, true);


            // $duration = ServiceDuration::find($request->duration_id);
            // $massage_type = ServiceType::find($request->massage_type);

            //get therapists info
            // $therapistName = [];
            // $therapistImage = [];
            // $therapistIds = [];
            // $invoiceTableToThID = null;
            // foreach ($request->therapists as $key => $newth) {
            //     $objTh = User::find($newth);
            //     if (!$objTh) continue;

            //     $therapistName[] = trim($objTh->name);
            //     $therapistIds[] = trim($objTh->id);
            //     $therapistImage[] = trim($objTh->public_avatar_url);

            //     if ($request->invoice_table == "invoice_therapist_{$key}")
            //         $invoiceTableToThID = trim($objTh->id);
            // } //endforeach therapists

            $data = [
                'amount' => $request->amount,
                'hour' => $request->newhour,
                'date' => $request->newdate,
                'internal_notes' => $request->internal_notes,
            ];

            //start saving the booking
            DB::beginTransaction();

            //update bookiing details
            $status = $booking->update($data);

            //update booking therapists:
            //1. detach all boking therapist
            // $booking->therapists()->detach();
            //2. attach new therapist with date, hour, duration details
            // foreach ($therapistIds as $thid) {
            //     if ($invoiceTableToThID == $thid)
            //         $invoice_table = 1;
            //     else
            //         $invoice_table = 0;
            //     $booking->therapists()->attach($thid, ['date' => $request->newdate, 'hour' => $request->newhour, 'duration' => $duration->duration, 'invoice_table' => $invoice_table]);
            // }

            //check the booking update status and commit/rollback database transaction
            if ($status) {

                //commit
                DB::commit();

                //inform user about the action
                flash(trans('schedules::booking.message_success_update'), 'info');

                //send email to customer with the new booking details
                // $this->sendOrderMail($booking);

                //redirect to booking details page
                return redirect(route('admin.schedules.bookings.show', ['id' => $booking->id]));
            } else {
                //rollback
                DB::rollBack();

                //redirect back to edit page
                return redirect(route('admin.schedules.bookings.edit', ['id' => $booking->id]));
            } //end transaction

            //redirect
            return redirect(route('admin.schedules.bookings.show', ['id' => $booking->id]));
        } else {
            //for Face 2 Face
            //get booking
            $booking = BookingOrder::where('id', $id)->withoutGlobalScope(ActiveScope::class)->first();
            $orderInfo = json_decode($booking->orderInfo, true);


            $duration = ServiceDuration::find($request->duration_id);
            $massage_type = ServiceType::find($request->massage_type);

            //get therapists info
            $therapistName = [];
            $therapistImage = [];
            $therapistIds = [];
            $invoiceTableToThID = null;
            foreach ($request->therapists as $key => $newth) {
                $objTh = User::find($newth);
                if (!$objTh) continue;

                $therapistName[] = trim($objTh->name);
                $therapistIds[] = trim($objTh->id);
                $therapistImage[] = trim($objTh->public_avatar_url);

                if ($request->invoice_table == "invoice_therapist_{$key}")
                    $invoiceTableToThID = trim($objTh->id);
            } //endforeach therapists

            $data = [
                'amount' => $request->amount,
                'hour' => $request->newhour,
                'date' => $request->newdate,
                'duration' => $duration->name,
                'duration_min' => $duration->duration,
                'massage_type' => $massage_type->name,
                'address' => trim($request->address),
                'location' => trim($request->location),
                'locationGeo' => json_encode([
                    'lat' => $request->locationGeoLat,
                    'lng' => $request->locationGeoLng,
                ]),
                'internal_notes' => $request->internal_notes,
                'orderInfo' => json_encode([
                    'therapist' => $therapistName,
                    'therapistIds' => $therapistIds,
                    'therapistImage' => $therapistImage,
                    'therapistsNo' => $orderInfo['therapistsNo'],
                    'therapistsOpt' => $orderInfo['therapistsOpt'],
                    'type' => $orderInfo['type'],
                    'date' => Carbon::createFromFormat('Y-m-d', $request->newdate)->format('d M Y'),
                    'hour' => $request->newhour,
                    'duration' => $duration->name,
                    'duration_min' => $duration->duration,
                    'duration_id' => $duration->id,
                    'duration_commision' => $orderInfo['duration_commision'],
                    'massage_type' => $massage_type->name,
                    'massage_type_id' => $massage_type->id,
                    'focal_points' => $orderInfo['focal_points'],
                    'can_order_table' => $orderInfo['can_order_table'],
                    'disclaimer' => $orderInfo['disclaimer'],
                    'has_table' => (bool)$request->has_table,
                    'table_value' => (bool)$request->has_table ? env('TABLE_VALUE', 9.99) : 0,
                    'has_transport' => ($request->transport_cost != 0) ? true : false,
                    'transport_cost' => $request->transport_cost,
                    'has_voucher' => $orderInfo['has_voucher'],
                    'voucher' => array_key_exists('voucher', $orderInfo) ? $orderInfo['voucher'] : [],
                    'user_name' => $request->user_name,
                    'user_phone' => $request->user_phone,
                    'address' => $request->address,
                    'postcode' => $request->postcode,
                    'county' => $request->county,
                    'location' => $request->location,
                    'locationGeo' => [
                        'lat' => $request->locationGeoLat,
                        'lng' => $request->locationGeoLng,
                    ],
                    'price_net' => $orderInfo['price_net'],
                    'amount' => $request->amount,
                    'has_extension' => isset($orderInfo['has_extension']) ? $orderInfo['has_extension'] : false,
                    'extension' => isset($orderInfo['extension']) ? $orderInfo['extension'] : [],
                ]),
            ];

            //start saving the booking
            DB::beginTransaction();

            //update bookiing details
            $status = $booking->update($data);

            if (!empty($request->internal_notes)) {
                //add internal note
                $note = new BookingInternalNote();
                $note->booking_id = $booking->id;
                $note->text_body = $request->internal_notes;
                $note->save();
            }
            //update booking therapists:
            //1. detach all boking therapist
            $booking->therapists()->detach();
            //2. attach new therapist with date, hour, duration details
            foreach ($therapistIds as $thid) {
                if ($invoiceTableToThID == $thid)
                    $invoice_table = 1;
                else
                    $invoice_table = 0;
                $booking->therapists()->attach($thid, ['date' => $request->newdate, 'hour' => $request->newhour, 'duration' => $duration->duration, 'invoice_table' => $invoice_table]);
            }

            //check the booking update status and commit/rollback database transaction
            if ($status) {

                //commit
                DB::commit();

                //inform user about the action
                flash(trans('schedules::booking.message_success_update'), 'info');

                //send email to customer with the new booking details
                $this->sendOrderMail($booking);

                //redirect to booking details page
                return redirect(route('admin.schedules.bookings.show', ['booking' => $booking->id]));
            } else {
                //rollback
                DB::rollBack();

                //redirect back to edit page
                return redirect(route('admin.schedules.bookings.edit', ['booking' => $booking->id]));
            } //end transaction


            //        //update hour
            //        if ($data['hour'] && $data['date']){
            //
            //            $orderInfo['hour'] = $data['hour'];
            //            $orderInfo['date'] = $data['date'];
            //
            //            $booking->date = $data['date'];
            //            $booking->hour = $data['hour'];
            //            $booking->orderInfo = json_encode($orderInfo);
            //            $booking->save();
            //
            //            foreach($booking->therapists as $therapist){
            //                $thID = $therapist->id;
            //                $booking->therapists()->updateExistingPivot($thID,['date'=>$data['date'], 'hour'=>$data['hour']]);
            //            } //endforeach
            //        } //endif hour

            //send email
            //        $this->sendOrderMail($booking);

            //inform user about the status of the update action
            //        flash(trans('schedules::booking.message_success_update'),'info');

            //redirect
            return redirect(route('admin.schedules.bookings.show', ['id' => $booking->id]));
        }
    }

    /**
     * Generate invoice for the selected booking
     *
     * @param $id
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function create_invoice($id)
    {
        //get booking
        $booking = BookingOrder::where('id', $id)->withoutGlobalScope(ActiveScope::class)->first();

        if (!$booking) {
            flash('Booking not found!', 'danger');
            return redirect(route('admin.schedules.bookings.index'));
        } //endif

        //create invoice repository object
        $repo = new BookingInvoiceRepository();
        if ($booking->salon_id) {
            //generate invoice
            $repo->new_salon_invoice($booking);
        } else {
            //generate invoice
            $repo->new_invoice($booking);
        }

        //return to booking index
        return redirect(route('admin.schedules.bookings.index'));
    }

    /**
     * Get available hours
     * @param $date
     * @param $therapistIds
     * @return mixed
     */
    public function get_hours($date, $therapistIds)
    {
        $hours = collect($this->repo->hours_without_buffer($date, $therapistIds));

        if ($hours->isEmpty()) {
            $results[''] = trans('schedules::booking.text_other_no_av_hours');
            return $results;
        }

        $avhours = $hours->filter(function ($data, $key) {
            return $data['available'];
        });

        if ($avhours->isEmpty()) {
            $results[''] = trans('schedules::booking.text_other_no_av_hours');
            return $results;
        } //endif

        $results[''] = trans('schedules::booking.text_other_av_hours');
        $results += $avhours->pluck('hour', 'hour')->toArray();

        return $results;
    }

    /**
     * Get hours with post request
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
     */
    public function get_post_hours(Request $request)
    {
        $booking = session('booking');

        $data = $this->get_hours($booking['date'], $booking['selected_therapists']);

        //return get available hours for requested date
        return response($data, 200);
    }


    /**
     * Set new booking date
     * @param $date
     */
    public function set_date(Request $request)
    {
        $date = $request->date;
        $booking = Session::get('booking');

        //if selected date is marked as day off, return empty hours array
        $daysOff = $this->repo->days_off($date);

        //        if ($daysOff->count())
        //            return response('no working day',403);

        //store the new date into session
        $booking['date'] = $date;
        Session::put('booking', $booking);
    }



    /**
     * Refund
     * @param $id
     */
    public function refund($id)
    {
        $obj = BookingOrder::where('id', $id)
            ->withoutGlobalScope(ActiveScope::class)
            ->first();
        if (!$obj) {
            flash('The booking is not found!', 'danger');
            return redirect(route('admin.schedules.bookings.show', ['booking_id' => $id]));
        } //endif

        $repo = new BookingRepository();
        try {
            if ($obj->is_active == 0) {
                $response = $repo->active_order($obj, true);
                // Modified by CIS
            } else {
                $response = $repo->cancel_order($obj, true);
            }
            $statusClass = $response['success'] ? 'info' : 'danger';

            flash($response['message'], $statusClass);
            return redirect(route('admin.schedules.bookings.show', ['booking_id' => $id]));
        } catch (\Exception $e) {
            flash($e->getMessage(), 'danger');
            return redirect(route('admin.schedules.bookings.show', ['booking_id' => $id]));
        }
    }

    /**
     * Send condfirmation order
     * @param $order
     */
    public function sendOrderMail($order)
    {
        $user = User::findOrFail($order->user_id);
        $data['user'] = $user;
        $data['order'] = $order;

        //send confirmation email
        Mail::send('schedules::frontend.emails.editorder', ['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(env('MAIL_NEWORDER_BCC'), env('MAIL_NEWORDER_BCC_NAME'));
            $m->bcc(explode(',', env('MAIL_NEWORDER_BCC')), env('MAIL_NEWORDER_BCC_NAME'));
            $m->subject('Tradze-Booking Updates');
        });
    }


    /**
     * Format text right
     * @param $string
     * @param bool $number
     * @return string
     */
    protected function text_right($string, $number = true)
    {
        $value = $string;
        if ($number)
            $value = number_format($string, 2, '.', ',') . " &pound;";


        return "<div class='text-right'>{$value}</div>";
    }

    public function getInternalNotes($bookingId)
    {
        $booking = BookingOrder::where('id', $bookingId)->withoutGlobalScope(ActiveScope::class)->first();
        if (!$booking) {
            flash('Booking not found!', 'danger');
            return redirect(route('admin.schedules.bookings.index'));
        } //endif

        //create data array
        $this->data['page_title'] = trans('schedules::booking.page_title');
        $this->data['booking'] = $booking;
        $this->data['internal_notes'] = BookingInternalNote::where('booking_id', $bookingId)->orderBy('created_at', 'desc')->get();
        //render page
        return view('schedules::admin.bookings.booking_internal_notes', $this->data);
    }

    public function removeInternalNotes(Request $request)
    {
        $noteId = $request->input('note_id');

        $note = BookingInternalNote::find($noteId);

        if (!$note) {
            return response()->json([
                'success' => false,
                'message' => 'Internal note not found.',
            ], 404);
        }

        $note->delete();

        return response()->json([
            'success' => true,
            'message' => 'Internal note removed successfully.',
        ]);
    }
}

ZeroDay Forums Mini