migrate to gtea from bistbucket

This commit is contained in:
2026-03-15 17:08:23 +07:00
commit 129ca2260c
3716 changed files with 566316 additions and 0 deletions

View File

@@ -0,0 +1,227 @@
<?php
namespace Modules\Booking\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Modules\Booking\Http\Requests\Booking\BookingStoreRequest;
use Modules\Booking\Http\Requests\Booking\BookingUpdateRequest;
use Modules\Booking\Models\Booking;
use Modules\Booking\Models\BookingItem;
class BookingController extends Controller
{
public function index(): JsonResponse
{
try {
$filters = request()->all();
$query = Booking::with([
'customer',
'hotel',
'bookingItems.room',
]);
// -----------------------------
// 🔍 SEARCHING
// -----------------------------
if (! empty($filters['search'])) {
$search = $filters['search'];
$query->whereHas('customer', function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%")
->orWhere('phone', 'LIKE', "%$search%");
})->orWhere('id', $search);
}
// -----------------------------
// 🎯 FILTERS
// -----------------------------
if (isset($filters['status'])) {
$query->where('status', $filters['status']);
}
if (! empty($filters['customer_id'])) {
$query->where('customer_id', $filters['customer_id']);
}
if (! empty($filters['hotel_id'])) {
$query->where('hotel_id', $filters['hotel_id']);
}
if (! empty($filters['check_in_from']) && ! empty($filters['check_in_to'])) {
$query->whereBetween('check_in', [$filters['check_in_from'], $filters['check_in_to']]);
}
if (! empty($filters['check_out_from']) && ! empty($filters['check_out_to'])) {
$query->whereBetween('check_out', [$filters['check_out_from'], $filters['check_out_to']]);
}
// -----------------------------
// 🔽 SORTING
// -----------------------------
$sortBy = $filters['sort_by'] ?? 'check_in';
$sortOrder = $filters['sort_order'] ?? 'desc';
$allowedSortColumns = ['id', 'check_in', 'check_out', 'status', 'created_at'];
if (! in_array($sortBy, $allowedSortColumns)) {
$sortBy = 'check_in';
}
$query->orderBy($sortBy, $sortOrder);
// -----------------------------
// 📄 PAGINATION
// -----------------------------
$perPage = $filters['per_page'] ?? 20;
$bookings = $query->paginate($perPage);
return $this->responseSuccess($bookings, 'Bookings fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(BookingStoreRequest $request): JsonResponse
{
$data = $request->validated();
DB::beginTransaction();
try {
// Create main booking
$booking = Booking::create([
'restaurant_id' => getUserRestaurantId(),
'hotel_id' => $data['hotel_id'],
'customer_id' => $data['customer_id'],
'check_in' => $data['check_in'],
'check_out' => $data['check_out'],
'check_in_time' => $data['check_in_time'] ?? null,
'check_out_time' => $data['check_out_time'] ?? null,
'total_adults' => $data['total_adults'],
'total_children' => $data['total_children'],
'subtotal_amount' => $data['subtotal_amount'],
'tax_amount' => $data['tax_amount'] ?? 0,
'discount_amount' => $data['discount_amount'] ?? 0,
'total_amount' => $data['total_amount'],
'payment_status' => $data['payment_status'],
'payment_method' => $data['payment_method'] ?? null,
'channel' => $data['channel'] ?? null,
'status' => $data['status'],
'remarks' => $data['remarks'] ?? null,
]);
// Create booking items
foreach ($data['booking_items'] as $item) {
BookingItem::create([
'restaurant_id' => getUserRestaurantId(),
'booking_id' => $booking->id,
'room_id' => $item['room_id'],
'adults' => $item['adults'],
'children' => $item['children'],
'room_price' => $item['room_price'],
'nights' => $item['nights'],
'tax_amount' => $item['tax_amount'] ?? 0,
'total_amount' => $item['total_amount'],
'status' => $item['status'],
]);
}
DB::commit();
return $this->responseSuccess($booking->load('bookingItems'), 'Booking has been created successfully.');
} catch (Exception $e) {
DB::rollBack();
return $this->responseError([], $e->getMessage());
}
}
public function show(int $id): JsonResponse
{
try {
$booking = Booking::with('customer', 'hotel', 'bookingItems.room')->findOrFail($id);
return $this->responseSuccess($booking, 'Booking has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function update(BookingUpdateRequest $request, int $id): JsonResponse
{
$data = $request->validated();
$booking = Booking::findOrFail($id);
DB::beginTransaction();
try {
// Update booking main data
$booking->update($data);
if (isset($data['booking_items']) && is_array($data['booking_items'])) {
$sentIds = collect($data['booking_items'])
->pluck('id') // existing items should send 'id'
->filter()
->toArray();
// DELETE only removed items
$booking->bookingItems()
->whereNotIn('id', $sentIds)
->delete();
foreach ($data['booking_items'] as $item) {
if (! empty($item['id'])) {
// → Update existing
$booking->bookingItems()
->where('id', $item['id'])
->update([
'restaurant_id' => $data['restaurant_id'] ?? $booking->restaurant_id,
'room_id' => $item['room_id'],
'adults' => $item['adults'],
'children' => $item['children'],
'room_price' => $item['room_price'],
'nights' => $item['nights'],
'tax_amount' => $item['tax_amount'] ?? 0,
'total_amount' => $item['total_amount'],
'status' => $item['status'] ?? 1,
]);
} else {
// → Create new
$booking->bookingItems()->create([
'restaurant_id' => $data['restaurant_id'] ?? $booking->restaurant_id,
'room_id' => $item['room_id'],
'adults' => $item['adults'],
'children' => $item['children'],
'room_price' => $item['room_price'],
'nights' => $item['nights'],
'tax_amount' => $item['tax_amount'] ?? 0,
'total_amount' => $item['total_amount'],
'status' => $item['status'] ?? 1,
]);
}
}
}
DB::commit();
return $this->responseSuccess($booking->load('bookingItems.room'), 'Booking updated successfully.');
} catch (Exception $e) {
DB::rollBack();
return $this->responseError([], $e->getMessage());
}
}
public function destroy(int $id): JsonResponse
{
try {
$booking = Booking::with('customer', 'hotel', 'bookingItems.room')->findOrFail($id);
$booking->delete();
return $this->responseSuccess([], 'Booking has been deleted successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Modules\Booking\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Booking\Http\Requests\Floor\FloorStoreRequest;
use Modules\Booking\Http\Requests\Floor\FloorUpdateRequest;
use Modules\Booking\Repositories\FloorRepository;
class FloorController extends Controller
{
public function __construct(private FloorRepository $repo) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getAll(request()->all()), 'Floor has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(FloorStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess($this->repo->create($request->all()), 'Floor has been created successfully.');
} catch (\Illuminate\Database\QueryException $exception) {
return $this->responseError([], 'Database error: '.$exception->getMessage());
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getById($id), 'Floor has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function update(FloorUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->update($id, $request->all()), 'Floor has been updated successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->delete($id), 'Floor has been deleted successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Modules\Booking\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Booking\Http\Requests\Hotel\HotelStoreRequest;
use Modules\Booking\Http\Requests\Hotel\HotelUpdateRequest;
use Modules\Booking\Repositories\HotelRepository;
class HotelController extends Controller
{
public function __construct(private HotelRepository $repo) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getAll(request()->all()), 'Hotel has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(HotelStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess($this->repo->create($request->all()), 'Hotel has been created successfully.');
} catch (\Illuminate\Database\QueryException $exception) {
return $this->responseError([], 'Database error: '.$exception->getMessage());
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getById($id), 'Hotel has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function update(HotelUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->update($id, $request->all()), 'Hotel has been updated successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->delete($id), 'Hotel has been deleted successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Modules\Booking\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Booking\Http\Requests\RoomAvailability\RoomAvailabilityStoreRequest;
use Modules\Booking\Http\Requests\RoomAvailability\RoomAvailabilityUpdateRequest;
use Modules\Booking\Repositories\RoomAvailabilityRepository;
class RoomAvailabilityController extends Controller
{
public function __construct(private RoomAvailabilityRepository $repo) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getAll(request()->all()), 'RoomAvailability has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(RoomAvailabilityStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess($this->repo->create($request->all()), 'RoomAvailability has been created successfully.');
} catch (\Illuminate\Database\QueryException $exception) {
return $this->responseError([], 'Database error: '.$exception->getMessage());
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getById($id), 'RoomAvailability has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function update(RoomAvailabilityUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->update($id, $request->all()), 'RoomAvailability has been updated successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->delete($id), 'RoomAvailability has been deleted successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Modules\Booking\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Booking\Http\Requests\RoomBlock\RoomBlockStoreRequest;
use Modules\Booking\Http\Requests\RoomBlock\RoomBlockUpdateRequest;
use Modules\Booking\Repositories\RoomBlockRepository;
class RoomBlockController extends Controller
{
public function __construct(private RoomBlockRepository $repo) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getAll(request()->all()), 'RoomBlock has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(RoomBlockStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess($this->repo->create($request->all()), 'RoomBlock has been created successfully.');
} catch (\Illuminate\Database\QueryException $exception) {
return $this->responseError([], 'Database error: '.$exception->getMessage());
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getById($id), 'RoomBlock has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function update(RoomBlockUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->update($id, $request->all()), 'RoomBlock has been updated successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->delete($id), 'RoomBlock has been deleted successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Modules\Booking\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Booking\Http\Requests\Room\RoomStoreRequest;
use Modules\Booking\Http\Requests\Room\RoomUpdateRequest;
use Modules\Booking\Repositories\RoomRepository;
class RoomController extends Controller
{
public function __construct(private RoomRepository $repo) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getAll(request()->all()), 'Room has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(RoomStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess($this->repo->create($request->all()), 'Room has been created successfully.');
} catch (\Illuminate\Database\QueryException $exception) {
return $this->responseError([], 'Database error: '.$exception->getMessage());
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getById($id), 'Room has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function update(RoomUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->update($id, $request->all()), 'Room has been updated successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->delete($id), 'Room has been deleted successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Modules\Booking\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Booking\Http\Requests\RoomType\RoomTypeStoreRequest;
use Modules\Booking\Http\Requests\RoomType\RoomTypeUpdateRequest;
use Modules\Booking\Repositories\RoomTypeRepository;
class RoomTypeController extends Controller
{
public function __construct(private RoomTypeRepository $repo) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getAll(request()->all()), 'RoomType has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(RoomTypeStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess($this->repo->create($request->all()), 'RoomType has been created successfully.');
} catch (\Illuminate\Database\QueryException $exception) {
return $this->responseError([], 'Database error: '.$exception->getMessage());
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getById($id), 'RoomType has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function update(RoomTypeUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->update($id, $request->all()), 'RoomType has been updated successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->delete($id), 'RoomType has been deleted successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace Modules\Booking\Http\Requests\Booking;
use Illuminate\Foundation\Http\FormRequest;
class BookingStoreRequest extends FormRequest
{
public function rules(): array
{
return [
'hotel_id' => 'required|exists:hotels,id',
'customer_id' => 'required|exists:customers,id',
'check_in' => 'required|date',
'check_out' => 'required|date|after_or_equal:check_in',
'check_in_time' => 'nullable|date_format:H:i:s',
'check_out_time' => 'nullable|date_format:H:i:s',
'total_adults' => 'required|integer|min:1',
'total_children' => 'required|integer|min:0',
'subtotal_amount' => 'required|numeric|min:0',
'tax_amount' => 'nullable|numeric|min:0',
'discount_amount' => 'nullable|numeric|min:0',
'total_amount' => 'required|numeric|min:0',
'payment_status' => 'required|in:pending,paid,refunded',
'payment_method' => 'nullable|in:cash,card,online,bank',
'channel' => 'nullable|string',
'status' => 'required|in:pending,confirmed,checked_in,checked_out,canceled',
'remarks' => 'nullable|string',
'booking_items' => 'required|array|min:1',
'booking_items.*.room_id' => 'required|exists:rooms,id',
'booking_items.*.adults' => 'required|integer|min:1',
'booking_items.*.children' => 'required|integer|min:0',
'booking_items.*.room_price' => 'required|numeric|min:0',
'booking_items.*.nights' => 'required|integer|min:1',
'booking_items.*.tax_amount' => 'nullable|numeric|min:0',
'booking_items.*.total_amount' => 'required|numeric|min:0',
'booking_items.*.status' => 'required|in:reserved,occupied,cleaning,completed,canceled',
];
}
public function messages(): array
{
return [
'booking_items.required' => 'At least one room must be added.',
'booking_items.*.room_id.exists' => 'The selected room does not exist.',
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Modules\Booking\Http\Requests\Booking;
use Illuminate\Foundation\Http\FormRequest;
class BookingUpdateRequest extends FormRequest
{
public function rules(): array
{
return [
'hotel_id' => 'nullable|exists:hotels,id',
'customer_id' => 'nullable|exists:customers,id',
'check_in' => 'nullable|date',
'check_out' => 'nullable|date|after_or_equal:check_in',
'check_in_time' => 'nullable|date_format:H:i:s',
'check_out_time' => 'nullable|date_format:H:i:s',
'total_adults' => 'nullable|integer|min:1',
'total_children' => 'nullable|integer|min:0',
'subtotal_amount' => 'nullable|numeric|min:0',
'tax_amount' => 'nullable|numeric|min:0',
'discount_amount' => 'nullable|numeric|min:0',
'total_amount' => 'nullable|numeric|min:0',
'payment_status' => 'nullable|in:pending,paid,refunded',
'payment_method' => 'nullable|in:cash,card,online,bank',
'channel' => 'nullable|string',
'status' => 'nullable|in:pending,confirmed,checked_in,checked_out,canceled',
'remarks' => 'nullable|string',
'booking_items' => 'nullable|array|min:1',
'booking_items.*.room_id' => 'required_with:booking_items|exists:rooms,id',
'booking_items.*.adults' => 'required_with:booking_items|integer|min:1',
'booking_items.*.children' => 'required_with:booking_items|integer|min:0',
'booking_items.*.room_price' => 'required_with:booking_items|numeric|min:0',
'booking_items.*.nights' => 'required_with:booking_items|integer|min:1',
'booking_items.*.tax_amount' => 'nullable|numeric|min:0',
'booking_items.*.total_amount' => 'required_with:booking_items|numeric|min:0',
'booking_items.*.status' => 'required_with:booking_items|in:reserved,occupied,cleaning,completed,canceled',
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace Modules\Booking\Http\Requests\Booking;
use Illuminate\Foundation\Http\FormRequest;
class CustomerBookingStoreRequest extends FormRequest
{
public function rules(): array
{
return [
'hotel_id' => 'required|exists:hotels,id',
// 'customer_id' => 'required|exists:customers,id',
'check_in' => 'required|date',
'check_out' => 'required|date|after_or_equal:check_in',
'check_in_time' => 'nullable|date_format:H:i:s',
'check_out_time' => 'nullable|date_format:H:i:s',
'total_adults' => 'required|integer|min:1',
'total_children' => 'required|integer|min:0',
'subtotal_amount' => 'required|numeric|min:0',
'tax_amount' => 'nullable|numeric|min:0',
'discount_amount' => 'nullable|numeric|min:0',
'total_amount' => 'required|numeric|min:0',
'payment_status' => 'required|in:pending,paid,refunded',
'payment_method' => 'nullable|in:cash,card,online,bank',
'channel' => 'nullable|string',
'status' => 'required|in:pending,confirmed,checked_in,checked_out,canceled',
'remarks' => 'nullable|string',
'booking_items' => 'required|array|min:1',
'booking_items.*.room_id' => 'required|exists:rooms,id',
'booking_items.*.adults' => 'required|integer|min:1',
'booking_items.*.children' => 'required|integer|min:0',
'booking_items.*.room_price' => 'required|numeric|min:0',
'booking_items.*.nights' => 'required|integer|min:1',
'booking_items.*.tax_amount' => 'nullable|numeric|min:0',
'booking_items.*.total_amount' => 'required|numeric|min:0',
'booking_items.*.status' => 'required|in:reserved,occupied,cleaning,completed,canceled',
];
}
public function messages(): array
{
return [
'booking_items.required' => 'At least one room must be added.',
'booking_items.*.room_id.exists' => 'The selected room does not exist.',
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Modules\Booking\Http\Requests\Floor;
use Illuminate\Foundation\Http\FormRequest;
class FloorStoreRequest extends FormRequest
{
public function rules(): array
{
return [
'hotel_id' => ['required', 'exists:hotels,id'],
'name' => ['required', 'string', 'max:255'],
'level' => ['nullable', 'integer', 'min:-5', 'max:200'],
'status' => ['nullable', 'integer', 'in:0,1'],
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Modules\Booking\Http\Requests\Floor;
use Illuminate\Foundation\Http\FormRequest;
class FloorUpdateRequest extends FormRequest
{
public function rules(): array
{
return [
'hotel_id' => ['required', 'exists:hotels,id'],
'name' => ['required', 'string', 'max:255'],
'level' => ['nullable', 'integer', 'min:-5', 'max:200'],
'status' => ['nullable', 'integer', 'in:0,1'],
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Modules\Booking\Http\Requests\Hotel;
use Illuminate\Foundation\Http\FormRequest;
class HotelStoreRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'location' => ['nullable', 'string', 'max:255'],
'email' => ['nullable', 'email', 'max:255'],
'phone' => ['nullable', 'string', 'max:30'],
'description' => ['nullable', 'string'],
'latitude' => ['nullable', 'numeric', 'between:-90,90'],
'longitude' => ['nullable', 'numeric', 'between:-180,180'],
'check_in_time' => ['nullable', 'date_format:H:i'],
'check_out_time' => ['nullable', 'date_format:H:i'],
'status' => ['required', 'integer', 'in:0,1'],
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Modules\Booking\Http\Requests\Hotel;
use Illuminate\Foundation\Http\FormRequest;
class HotelUpdateRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'location' => ['nullable', 'string', 'max:255'],
'email' => ['nullable', 'email', 'max:255'],
'phone' => ['nullable', 'string', 'max:30'],
'description' => ['nullable', 'string'],
'latitude' => ['nullable', 'numeric', 'between:-90,90'],
'longitude' => ['nullable', 'numeric', 'between:-180,180'],
'check_in_time' => ['nullable', 'date_format:H:i'],
'check_out_time' => ['nullable', 'date_format:H:i'],
'status' => ['required', 'integer', 'in:0,1'],
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Modules\Booking\Http\Requests\Room;
use Illuminate\Foundation\Http\FormRequest;
class RoomStoreRequest extends FormRequest
{
public function rules(): array
{
return [
'hotel_id' => ['required', 'integer', 'exists:hotels,id'],
'floor_id' => ['required', 'integer', 'exists:floors,id'],
'room_type_id' => ['required', 'integer', 'exists:room_types,id'],
'room_number' => ['required', 'string', 'max:50'],
'room_code' => ['nullable', 'string', 'max:100'],
'max_adults' => ['required', 'integer', 'min:1'],
'max_children' => ['required', 'integer', 'min:0'],
'has_balcony' => ['boolean'],
'has_bathtub' => ['boolean'],
'view_type' => ['nullable', 'string', 'max:50'],
'slug' => ['required', 'string', 'max:100'],
'image' => ['nullable', 'file', 'image'],
'banner_image' => ['nullable', 'file', 'image'],
'gallery_images' => ['nullable', 'array'],
'gallery_images.*' => ['file', 'image'],
'description' => ['nullable', 'string'],
'regular_price' => ['required', 'numeric', 'min:0'],
'offer_price' => ['nullable', 'numeric', 'min:0'],
'is_clean' => ['nullable', 'boolean'],
'is_available' => ['nullable', 'boolean'],
'status' => ['nullable', 'integer', 'in:0,1'],
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Modules\Booking\Http\Requests\Room;
use Illuminate\Foundation\Http\FormRequest;
class RoomUpdateRequest extends FormRequest
{
public function rules(): array
{
return [
'hotel_id' => ['required', 'integer', 'exists:hotels,id'],
'floor_id' => ['required', 'integer', 'exists:floors,id'],
'room_type_id' => ['required', 'integer', 'exists:room_types,id'],
'room_number' => ['required', 'string', 'max:50'],
'room_code' => ['nullable', 'string', 'max:100'],
'max_adults' => ['required', 'integer', 'min:1'],
'max_children' => ['required', 'integer', 'min:0'],
'has_balcony' => ['boolean'],
'has_bathtub' => ['boolean'],
'view_type' => ['nullable', 'string', 'max:50'],
'slug' => ['required', 'string', 'max:100'],
'image' => ['nullable', 'file', 'image'],
'banner_image' => ['nullable', 'file', 'image'],
'gallery_images' => ['nullable', 'array'],
'gallery_images.*' => ['file', 'image'],
'description' => ['nullable', 'string'],
'regular_price' => ['required', 'numeric', 'min:0'],
'offer_price' => ['nullable', 'numeric', 'min:0'],
'is_clean' => ['nullable', 'boolean'],
'is_available' => ['nullable', 'boolean'],
'status' => ['nullable', 'integer', 'in:0,1'],
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Modules\Booking\Http\Requests\RoomAvailability;
use Illuminate\Foundation\Http\FormRequest;
class RoomAvailabilityStoreRequest extends FormRequest
{
public function rules()
{
return [
'hotel_id' => 'required|exists:hotels,id',
'room_id' => 'required|exists:rooms,id',
'total_inventory' => 'required|integer|min:1',
'available_inventory' => 'required|integer|min:0',
'date' => 'required|date',
'is_available' => 'boolean',
'is_closed_to_arrival' => 'boolean',
'is_closed_to_departure' => 'boolean',
'base_price' => 'nullable|numeric|min:0',
'extra_adult_price' => 'nullable|numeric|min:0',
'extra_child_price' => 'nullable|numeric|min:0',
'min_stay' => 'integer|min:1',
'max_stay' => 'nullable|integer|min:1',
'blocked_by_booking_id' => 'nullable|exists:bookings,id',
'block_type' => 'in:none,booking,maintenance,manual',
'note' => 'nullable|string',
'status' => 'integer|in:0,1',
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Modules\Booking\Http\Requests\RoomAvailability;
use Illuminate\Foundation\Http\FormRequest;
class RoomAvailabilityUpdateRequest extends FormRequest
{
public function rules(): array
{
return [
'hotel_id' => 'required|exists:hotels,id',
'room_id' => 'required|exists:rooms,id',
'total_inventory' => 'required|integer|min:1',
'available_inventory' => 'required|integer|min:0',
'date' => 'required|date',
'is_available' => 'boolean',
'is_closed_to_arrival' => 'boolean',
'is_closed_to_departure' => 'boolean',
'base_price' => 'nullable|numeric|min:0',
'extra_adult_price' => 'nullable|numeric|min:0',
'extra_child_price' => 'nullable|numeric|min:0',
'min_stay' => 'integer|min:1',
'max_stay' => 'nullable|integer|min:1',
'blocked_by_booking_id' => 'nullable|exists:bookings,id',
'block_type' => 'in:none,booking,maintenance,manual',
'note' => 'nullable|string',
'status' => 'integer|in:0,1',
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Modules\Booking\Http\Requests\RoomBlock;
use Illuminate\Foundation\Http\FormRequest;
class RoomBlockStoreRequest extends FormRequest
{
public function rules(): array
{
return [
'hotel_id' => 'nullable|exists:hotels,id',
'room_id' => 'required|exists:rooms,id',
'start_date' => 'required|date',
'end_date' => 'required|date|after_or_equal:start_date',
'start_time' => 'nullable|date_format:H:i:s',
'end_time' => 'nullable|date_format:H:i:s|after:start_time',
'block_type' => 'required|in:maintenance,deep_clean,renovation,owner_stay,event,other',
'blocked_inventory' => 'required|integer|min:1',
'priority' => 'integer|min:1',
'reason' => 'nullable|string|max:255',
'auto_release' => 'boolean',
'created_by' => 'nullable|exists:users,id',
'status' => 'nullable|in:0,1',
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Modules\Booking\Http\Requests\RoomBlock;
use Illuminate\Foundation\Http\FormRequest;
class RoomBlockUpdateRequest extends FormRequest
{
public function rules(): array
{
return [
'hotel_id' => 'nullable|exists:hotels,id',
'room_id' => 'required|exists:rooms,id',
'start_date' => 'required|date',
'end_date' => 'required|date|after_or_equal:start_date',
'start_time' => 'nullable|date_format:H:i:s',
'end_time' => 'nullable|date_format:H:i:s|after:start_time',
'block_type' => 'required|in:maintenance,deep_clean,renovation,owner_stay,event,other',
'blocked_inventory' => 'required|integer|min:1',
'priority' => 'integer|min:1',
'reason' => 'nullable|string|max:255',
'auto_release' => 'boolean',
'created_by' => 'nullable|exists:users,id',
'status' => 'nullable|in:0,1',
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Modules\Booking\Http\Requests\RoomType;
use Illuminate\Foundation\Http\FormRequest;
class RoomTypeStoreRequest extends FormRequest
{
public function rules(): array
{
return [
'hotel_id' => ['required', 'exists:hotels,id'],
// Basic info
'name' => ['required', 'string', 'max:255'],
'capacity' => ['required', 'integer', 'min:1', 'max:20'],
// Room Features
'beds' => ['required', 'integer', 'min:1', 'max:10'],
'bed_type' => ['nullable', 'string', 'max:100'],
'has_ac' => ['boolean'],
'has_wifi' => ['boolean'],
'has_breakfast' => ['boolean'],
'is_refundable' => ['boolean'],
// Pricing
'base_price' => ['required', 'numeric', 'min:0'],
'weekend_price' => ['nullable', 'numeric', 'min:0'],
'extra_guest_price' => ['nullable', 'numeric', 'min:0'],
// Description
'description' => ['nullable', 'string'],
// Status
'status' => ['required', 'integer', 'in:0,1'],
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Modules\Booking\Http\Requests\RoomType;
use Illuminate\Foundation\Http\FormRequest;
class RoomTypeUpdateRequest extends FormRequest
{
public function rules(): array
{
return [
'hotel_id' => ['required', 'exists:hotels,id'],
// Basic info
'name' => ['required', 'string', 'max:255'],
'capacity' => ['required', 'integer', 'min:1', 'max:20'],
// Room Features
'beds' => ['required', 'integer', 'min:1', 'max:10'],
'bed_type' => ['nullable', 'string', 'max:100'],
'has_ac' => ['boolean'],
'has_wifi' => ['boolean'],
'has_breakfast' => ['boolean'],
'is_refundable' => ['boolean'],
// Pricing
'base_price' => ['required', 'numeric', 'min:0'],
'weekend_price' => ['nullable', 'numeric', 'min:0'],
'extra_guest_price' => ['nullable', 'numeric', 'min:0'],
// Description
'description' => ['nullable', 'string'],
// Status
'status' => ['required', 'integer', 'in:0,1'],
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace Modules\Booking\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Modules\Authentication\Models\User;
use Modules\Restaurant\Models\Customer;
class Booking extends Model
{
protected $fillable = [
'restaurant_id',
'hotel_id',
'customer_id',
'check_in',
'check_out',
'check_in_time',
'check_out_time',
'total_adults',
'total_children',
'subtotal_amount',
'tax_amount',
'discount_amount',
'total_amount',
'payment_status',
'payment_method',
'channel',
'status',
'canceled_at',
'canceled_by',
'remarks',
'created_at',
'updated_at',
'deleted_at',
];
/**
* Casts
*/
protected $casts = [
'restaurant_id' => 'integer',
'hotel_id' => 'integer',
'customer_id' => 'integer',
'check_in' => 'date',
'check_out' => 'date',
'check_in_time' => 'datetime:H:i',
'check_out_time' => 'datetime:H:i',
'total_adults' => 'integer',
'total_children' => 'integer',
'subtotal_amount' => 'decimal:2',
'tax_amount' => 'decimal:2',
'discount_amount' => 'decimal:2',
'total_amount' => 'decimal:2',
'canceled_at' => 'datetime',
'canceled_by' => 'integer',
];
public const TABLE_NAME = 'bookings';
protected $table = self::TABLE_NAME;
public function hotel(): BelongsTo
{
return $this->belongsTo(Hotel::class)->select('id', 'name');
}
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class)->select('id', 'name', 'phone', 'email', 'avatar');
}
public function bookingItems(): HasMany
{
return $this->hasMany(BookingItem::class);
}
public function rooms(): BelongsToMany
{
return $this->belongsToMany(Room::class, 'booking_items');
}
public function canceledBy(): BelongsTo
{
return $this->belongsTo(User::class, 'canceled_by');
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Modules\Booking\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class BookingItem extends Model
{
protected $fillable = [
'restaurant_id',
'booking_id',
'room_id',
'adults',
'children',
'room_price',
'nights',
'tax_amount',
'total_amount',
'status',
'created_at',
'updated_at',
'deleted_at',
];
public const TABLE_NAME = 'booking_items';
protected $table = self::TABLE_NAME;
public function booking(): BelongsTo
{
return $this->belongsTo(Booking::class);
}
public function room(): BelongsTo
{
return $this->belongsTo(Room::class)->select('id', 'room_number', 'room_code', 'image');
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Modules\Booking\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Floor extends Model
{
protected $fillable = [
'restaurant_id',
'hotel_id',
'name',
'level',
'status',
'created_at',
'updated_at',
'deleted_at',
];
public const TABLE_NAME = 'floors';
protected $table = self::TABLE_NAME;
public function hotel(): BelongsTo
{
return $this->belongsTo(Hotel::class)->select('id', 'name');
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace Modules\Booking\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Modules\Authentication\Models\Restaurant;
class Hotel extends Model
{
protected $fillable = [
'restaurant_id',
'name',
'location',
'email',
'phone',
'description',
'latitude',
'longitude',
'check_in_time',
'check_out_time',
'status',
];
/**
* Casts
*/
protected $casts = [
'latitude' => 'decimal:7',
'longitude' => 'decimal:7',
'check_in_time' => 'datetime:H:i',
'check_out_time' => 'datetime:H:i',
'status' => 'integer',
];
public const TABLE_NAME = 'hotels';
protected $table = self::TABLE_NAME;
public function restaurant(): BelongsTo
{
return $this->belongsTo(Restaurant::class);
}
public function floors(): HasMany
{
return $this->hasMany(Floor::class);
}
public function roomTypes(): HasMany
{
return $this->hasMany(RoomType::class);
}
public function rooms(): HasMany
{
return $this->hasMany(Room::class);
}
public function bookings(): HasMany
{
return $this->hasMany(Booking::class);
}
}

View File

@@ -0,0 +1,79 @@
<?php
namespace Modules\Booking\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Room extends Model
{
protected $fillable = [
'restaurant_id',
'hotel_id',
'floor_id',
'room_type_id',
'room_number',
'room_code',
'slug',
'max_adults',
'max_children',
'has_balcony',
'has_bathtub',
'view_type',
'image',
'banner_image',
'gallery_images',
'description',
'regular_price',
'offer_price',
'is_clean',
'is_available',
'status',
'created_at',
'updated_at',
'deleted_at',
];
/**
* Casts
*/
protected $casts = [
'restaurant_id' => 'integer',
'hotel_id' => 'integer',
'floor_id' => 'integer',
'room_type_id' => 'integer',
'max_adults' => 'integer',
'max_children' => 'integer',
'has_balcony' => 'boolean',
'has_bathtub' => 'boolean',
'gallery_images' => 'array',
'is_clean' => 'boolean',
'is_available' => 'boolean',
'status' => 'integer',
];
public const TABLE_NAME = 'rooms';
protected $table = self::TABLE_NAME;
public function hotel(): BelongsTo
{
return $this->belongsTo(Hotel::class);
}
public function floor(): BelongsTo
{
return $this->belongsTo(Floor::class);
}
public function roomType(): BelongsTo
{
return $this->belongsTo(RoomType::class);
}
public function bookings(): HasMany
{
return $this->hasMany(BookingItem::class, 'room_id');
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace Modules\Booking\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class RoomAvailability extends Model
{
protected $fillable = [
'restaurant_id',
'hotel_id',
'room_id',
'date',
'total_inventory',
'available_inventory',
'is_available',
'is_closed_to_arrival',
'is_closed_to_departure',
'base_price',
'extra_adult_price',
'extra_child_price',
'min_stay',
'max_stay',
'blocked_by_booking_id',
'block_type',
'note',
'status',
'created_at',
'updated_at',
'deleted_at',
];
public const TABLE_NAME = 'room_availabilities';
protected $table = self::TABLE_NAME;
public function hotel(): BelongsTo
{
return $this->belongsTo(Hotel::class);
}
public function room(): BelongsTo
{
return $this->belongsTo(Room::class);
}
public function blockedByBooking(): BelongsTo
{
return $this->belongsTo(Booking::class, 'blocked_by_booking_id');
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Modules\Booking\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Modules\Authentication\Models\User;
class RoomBlock extends Model
{
protected $fillable = [
'restaurant_id',
'hotel_id',
'room_id',
'start_date',
'end_date',
'start_time',
'end_time',
'block_type',
'blocked_inventory',
'priority',
'reason',
'auto_release',
'created_by',
'status',
'created_at',
'updated_at',
'deleted_at',
];
public const TABLE_NAME = 'room_blocks';
protected $table = self::TABLE_NAME;
public function hotel(): BelongsTo
{
return $this->belongsTo(Hotel::class);
}
public function room(): BelongsTo
{
return $this->belongsTo(Room::class);
}
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Modules\Booking\Models;
use Illuminate\Database\Eloquent\Model;
class RoomPrice extends Model
{
protected $fillable = [
'restaurant_id',
'room_id',
'start_date',
'end_date',
'day_type',
'price',
'priority',
'is_active',
];
/**
* Casts
*/
protected $casts = [
'restaurant_id' => 'integer',
'room_id' => 'integer',
'start_date' => 'date',
'end_date' => 'date',
'price' => 'decimal:2',
'priority' => 'integer',
'is_active' => 'boolean',
];
public const TABLE_NAME = 'room_prices';
protected $table = self::TABLE_NAME;
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Modules\Booking\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class RoomType extends Model
{
protected $fillable = [
'restaurant_id',
'hotel_id',
'name',
'capacity',
'beds',
'bed_type',
'has_ac',
'has_wifi',
'has_breakfast',
'is_refundable',
'base_price',
'weekend_price',
'extra_guest_price',
'description',
'status',
'created_at',
'updated_at',
'deleted_at',
];
/**
* Casts
*/
protected $casts = [
'restaurant_id' => 'integer',
'hotel_id' => 'integer',
'capacity' => 'integer',
'beds' => 'integer',
'has_ac' => 'boolean',
'has_wifi' => 'boolean',
'has_breakfast' => 'boolean',
'is_refundable' => 'boolean',
'base_price' => 'decimal:2',
'weekend_price' => 'decimal:2',
'extra_guest_price' => 'decimal:2',
'status' => 'integer',
];
public const TABLE_NAME = 'room_types';
protected $table = self::TABLE_NAME;
public function hotel(): BelongsTo
{
return $this->belongsTo(Hotel::class);
}
public function rooms(): HasMany
{
return $this->hasMany(Room::class);
}
}

View File

@@ -0,0 +1,154 @@
<?php
namespace Modules\Booking\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
use Nwidart\Modules\Traits\PathNamespace;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
class BookingServiceProvider extends ServiceProvider
{
use PathNamespace;
protected string $name = 'Booking';
protected string $nameLower = 'booking';
/**
* Boot the application events.
*/
public function boot(): void
{
$this->registerCommands();
$this->registerCommandSchedules();
$this->registerTranslations();
$this->registerConfig();
$this->registerViews();
$this->loadMigrationsFrom(module_path($this->name, 'database/migrations'));
}
/**
* Register the service provider.
*/
public function register(): void
{
$this->app->register(EventServiceProvider::class);
$this->app->register(RouteServiceProvider::class);
}
/**
* Register commands in the format of Command::class
*/
protected function registerCommands(): void
{
// $this->commands([]);
}
/**
* Register command Schedules.
*/
protected function registerCommandSchedules(): void
{
// $this->app->booted(function () {
// $schedule = $this->app->make(Schedule::class);
// $schedule->command('inspire')->hourly();
// });
}
/**
* Register translations.
*/
public function registerTranslations(): void
{
$langPath = resource_path('lang/modules/'.$this->nameLower);
if (is_dir($langPath)) {
$this->loadTranslationsFrom($langPath, $this->nameLower);
$this->loadJsonTranslationsFrom($langPath);
} else {
$this->loadTranslationsFrom(module_path($this->name, 'lang'), $this->nameLower);
$this->loadJsonTranslationsFrom(module_path($this->name, 'lang'));
}
}
/**
* Register config.
*/
protected function registerConfig(): void
{
$configPath = module_path($this->name, config('modules.paths.generator.config.path'));
if (is_dir($configPath)) {
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($configPath));
foreach ($iterator as $file) {
if ($file->isFile() && $file->getExtension() === 'php') {
$config = str_replace($configPath.DIRECTORY_SEPARATOR, '', $file->getPathname());
$config_key = str_replace([DIRECTORY_SEPARATOR, '.php'], ['.', ''], $config);
$segments = explode('.', $this->nameLower.'.'.$config_key);
// Remove duplicated adjacent segments
$normalized = [];
foreach ($segments as $segment) {
if (end($normalized) !== $segment) {
$normalized[] = $segment;
}
}
$key = ($config === 'config.php') ? $this->nameLower : implode('.', $normalized);
$this->publishes([$file->getPathname() => config_path($config)], 'config');
$this->merge_config_from($file->getPathname(), $key);
}
}
}
}
/**
* Merge config from the given path recursively.
*/
protected function merge_config_from(string $path, string $key): void
{
$existing = config($key, []);
$module_config = require $path;
config([$key => array_replace_recursive($existing, $module_config)]);
}
/**
* Register views.
*/
public function registerViews(): void
{
$viewPath = resource_path('views/modules/'.$this->nameLower);
$sourcePath = module_path($this->name, 'resources/views');
$this->publishes([$sourcePath => $viewPath], ['views', $this->nameLower.'-module-views']);
$this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->nameLower);
Blade::componentNamespace(config('modules.namespace').'\\'.$this->name.'\\View\\Components', $this->nameLower);
}
/**
* Get the services provided by the provider.
*/
public function provides(): array
{
return [];
}
private function getPublishableViewPaths(): array
{
$paths = [];
foreach (config('view.paths') as $path) {
if (is_dir($path.'/modules/'.$this->nameLower)) {
$paths[] = $path.'/modules/'.$this->nameLower;
}
}
return $paths;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Modules\Booking\Providers;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event handler mappings for the application.
*
* @var array<string, array<int, string>>
*/
protected $listen = [];
/**
* Indicates if events should be discovered.
*
* @var bool
*/
protected static $shouldDiscoverEvents = true;
/**
* Configure the proper event listeners for email verification.
*/
protected function configureEmailVerification(): void {}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Modules\Booking\Providers;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
protected string $name = 'Booking';
/**
* Called before routes are registered.
*
* Register any model bindings or pattern based filters.
*/
public function boot(): void
{
parent::boot();
}
/**
* Define the routes for the application.
*/
public function map(): void
{
$this->mapApiRoutes();
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*/
protected function mapApiRoutes(): void
{
Route::middleware('api')->prefix('api')->name('api.')->group(module_path($this->name, '/routes/api.php'));
}
}