/home2/mshostin/hall-management.ms-hostingladz.com/app/Http/Controllers/BookingController.php
<?php
namespace App\Http\Controllers;
use App\Http\Requests\BookingRequest;
use App\Models\Booking;
use App\Models\Hall;
use App\Services\BookingService;
use App\Services\CustomerService;
use App\Services\InvoiceService;
use Illuminate\Support\Facades\Storage;
use Carbon\Carbon;
class BookingController extends Controller
{
protected $customerService;
protected $bookingService;
protected $invoiceService;
public function __construct(CustomerService $customerService, BookingService $bookingService, InvoiceService $invoiceService)
{
$this->customerService = $customerService;
$this->bookingService = $bookingService;
$this->invoiceService = $invoiceService;
$this->middleware('permission:view-bookings')->only(['index', 'show', 'invoice']);
$this->middleware('permission:create-bookings')->only(['create', 'store']);
$this->middleware('permission:edit-bookings')->only(['edit', 'update']);
$this->middleware('permission:delete-bookings')->only(['destroy']);
}
public function index()
{
$this->authorize('viewAny', Booking::class);
$user = auth()->user();
// Fetch bookings based on role
if ($user->isSuperAdmin()) {
$bookings = Booking::with('customer', 'hall')->get();
// } elseif ($user->isHallAdmin()) {
// $bookings = Booking::with('customer', 'hall')
// ->where('hall_id', $user->hall_id)
// ->get();
} else {
// Other users with view-bookings permission
// $bookings = Booking::with('customer', 'hall')->get();
$bookings = Booking::with('customer', 'hall')
->where('hall_id', $user->hall_id)
->get();
}
// Prepare events for FullCalendar
$calendarEvents = $bookings->map(function ($b) {
return [
'id' => $b->id,
'title' => ($b->customer->name ?? 'Customer').' - '.($b->hall->name ?? 'Hall'),
'start' => $b->start_datetime,
'end' => $b->end_datetime,
'url' => route('bookings.show', $b->id),
];
});
return view('bookings.index', [
'bookings' => $bookings,
'calendarEvents' => $calendarEvents,
]);
}
public function create()
{
$user = auth()->user();
if ($user->hasRole('super_admin')) {
$halls = Hall::all();
} elseif ($user->hasRole('hall_admin')) {
if ($user->hall_id ?? false) {
$halls = Hall::where('id', $user->hall_id)->get();
} elseif ($user->halls()->exists()) {
$halls = $user->halls;
} else {
$halls = collect();
}
} else {
$halls = collect();
}
return view('bookings.create', compact('halls'));
}
// public function create()
// {
// $halls = \App\Models\Hall::all();
// return view('bookings.create', compact('halls'));
// }
public function store(BookingRequest $request)
{
$customer = $this->customerService->createOrUpdate([
'name' => $request->customer_name,
'phone' => $request->customer_phone,
'email' => $request->customer_email,
'cnic' => $request->customer_cnic,
'address' => $request->customer_address,
]);
if (! $this->bookingService->checkAvailability($request->lawn_id, $request->start_datetime, $request->end_datetime)) {
return back()->withErrors(['lawn_id' => 'Selected lawn is already booked for this time range.'])->withInput();
}
$booking = $this->bookingService->createBooking(array_merge(
$request->only([
'hall_id', 'start_datetime', 'end_datetime', 'capacity',
'quote_price', 'booking_price', 'advance_paid', 'payment_status', 'status', 'notes', 'facilities', 'lawn_id',
]),
['customer_id' => $customer->id]
));
// Generate invoice PDF
$invoiceData = $this->invoiceService->generateInvoicePdf($booking);
// Generate WhatsApp and Gmail URLs
$whatsappUrl = $this->invoiceService->generateWhatsAppUrl($booking, url($invoiceData['url']));
$gmailUrl = $this->invoiceService->generateGmailUrl($booking, url($invoiceData['url']));
return view('bookings.booking-success', [
'booking' => $booking,
'invoiceUrl' => $invoiceData['url'],
'whatsappUrl' => $whatsappUrl,
'gmailUrl' => $gmailUrl,
]);
}
public function show(Booking $booking)
{
$this->authorize('view', $booking);
$booking->load(['customer', 'hall', 'lawn']);
// Generate URLs
$filename = 'invoice_' . $booking->formatted_booking_number . '.pdf';
$invoiceUrl = \Illuminate\Support\Facades\Storage::disk('public')->url('invoices/' . $filename);
$fullInvoiceUrl = url($invoiceUrl);
$whatsappUrl = $this->invoiceService->generateWhatsAppUrl($booking, $fullInvoiceUrl);
$gmailUrl = $this->invoiceService->generateGmailUrl($booking, $fullInvoiceUrl);
return view('bookings.show', compact('booking', 'whatsappUrl', 'gmailUrl', 'invoiceUrl'));
}
public function edit(Booking $booking)
{
$start = $booking->start_datetime;
$end = $booking->end_datetime;
$hall = $booking->hall;
$lawns = $hall->lawns()->select('id', 'name', 'capacity')->get();
if ($start && $end) {
$startDate = \Carbon\Carbon::parse($start);
$endDate = \Carbon\Carbon::parse($end);
$lawns->transform(function ($lawn) use ($startDate, $endDate) {
// Check if any booking overlaps in time
$booking = Booking::where('lawn_id', $lawn->id)
->where(function ($query) use ($startDate, $endDate) {
$query->where('start_datetime', '<', $endDate)
->where('end_datetime', '>', $startDate);
})
->first();
if ($booking) {
$lawn->available = false;
$lawn->booked_from = $booking->start_datetime->format('d M Y h:i A');
$lawn->booked_to = $booking->end_datetime->format('d M Y h:i A');
} else {
$lawn->available = true;
$lawn->booked_from = null;
$lawn->booked_to = null;
}
return $lawn;
});
} else {
$lawns->transform(function ($lawn) {
$lawn->available = true;
$lawn->booked_from = null;
$lawn->booked_to = null;
return $lawn;
});
}
$halls = \App\Models\Hall::all();
$booking->load('customer');
return view('bookings.edit', compact('booking', 'halls', 'lawns'));
}
public function update(BookingRequest $request, Booking $booking)
{
$customer = $this->customerService->createOrUpdate([
'name' => $request->customer_name,
'phone' => $request->customer_phone,
'email' => $request->customer_email,
'cnic' => $request->customer_cnic,
'address' => $request->customer_address,
], $booking->customer_id);
if (! $this->bookingService->checkAvailability($request->lawn_id, $request->start_datetime, $request->end_datetime, $booking->id)) {
return back()->withErrors(['lawn_id' => 'Selected lawn is already booked for this time range.'])->withInput();
}
$this->bookingService->updateBooking($booking, array_merge(
$request->only([
'hall_id', 'start_datetime', 'end_datetime', 'capacity',
'quote_price', 'booking_price', 'advance_paid', 'payment_status', 'status', 'notes', 'facilities', 'lawn_id',
]),
['customer_id' => $customer->id]
));
return redirect()->route('bookings.show', $booking->id)->with('success', 'Booking updated successfully.');
}
public function invoice(Booking $booking)
{
$this->authorize('view', $booking);
$booking->load(['customer', 'hall', 'lawn']);
return view('bookings.invoice', compact('booking'));
}
}