diff --git a/app-modules/payment/resources/views/mails/new-booking-alert.blade.php b/app-modules/payment/resources/views/mails/new-booking-alert.blade.php
new file mode 100644
index 0000000..e609c2d
--- /dev/null
+++ b/app-modules/payment/resources/views/mails/new-booking-alert.blade.php
@@ -0,0 +1,30 @@
+
+# New EV Booking ( {{ $booking->ref_no }} )
+A new EV booking was created at {{ $booking->created_at }}.
+
+**Booking Summary**
+- **Route:** {{ $booking->route->name ?? 'N/A' }}
+- **Seat Options:** {{ $booking->vehicleOptions->map(fn($b) => "{$b->passenger_count} x {$b->vehicle_option->value}")->implode(', ') }}
+- **Pickup Location:** {{ $booking->pickup_address ?? 'N/A' }}
+- **Dropoff Location:** {{ $booking->dropoff_address ?? 'N/A' }}
+- **Travel Date:** {{ $booking->travel_date ?? 'N/A' }}
+- **Total Price:** {{ $booking->price ?? 'N/A' }}
+
+{{-- @if(!empty($booking->notes))
+**Notes:**
+{{ $booking->notes }}
+@endif --}}
+
+Payment Method: {{ ($payment->gateway ?? 'N/A') }}
+
+Contact Info: {{ ($booking->passenger_name ?? '') }} {{ $booking->passenger_phone ?? '' }}
+
+Channel: {{ $booking->created_by_channel ?? '-' }}
+
+
+View Booking
+
+
+Auto generated from
+{{ config('app.name') }}
+
diff --git a/app-modules/payment/src/Mail/NewBookingAlert.php b/app-modules/payment/src/Mail/NewBookingAlert.php
new file mode 100644
index 0000000..691563b
--- /dev/null
+++ b/app-modules/payment/src/Mail/NewBookingAlert.php
@@ -0,0 +1,61 @@
+booking = $payment->booking;
+ $this->url = BookingResource::getUrl('view', ['record' => $this->booking]);
+ }
+
+ /**
+ * Get the message envelope.
+ */
+ public function envelope(): Envelope
+ {
+ return new Envelope(
+ subject: 'FamousLY4 New Booking Alert',
+ );
+ }
+
+ /**
+ * Get the message content definition.
+ */
+ public function content(): Content
+ {
+ return new Content(
+ markdown: 'payment::mails.new-booking-alert',
+ );
+ }
+
+ /**
+ * Get the attachments for the message.
+ *
+ * @return array
+ */
+ public function attachments(): array
+ {
+ return [];
+ }
+}
diff --git a/app-modules/payment/src/Observers/PaymentObserver.php b/app-modules/payment/src/Observers/PaymentObserver.php
new file mode 100644
index 0000000..813abf2
--- /dev/null
+++ b/app-modules/payment/src/Observers/PaymentObserver.php
@@ -0,0 +1,35 @@
+status === PaymentStatus::Failed) return;
+
+ try {
+ $admin_emails = config('booking.admin_emails');
+
+ Mail::bcc($admin_emails)->queue(new NewBookingAlert($payment));
+ } catch (\Exception $e) {
+ // Log the exception or handle it as needed
+ \Log::error('Failed to send NewBookingAlert email: ' . $e->getMessage());
+ }
+ }
+
+ public function updated(Payment $payment): void
+ {
+ // Handle the event when a payment is updated for a booking
+ }
+
+ public function deleted(Payment $payment): void
+ {
+ // Handle the event when a payment is deleted for a booking
+ }
+}
diff --git a/app-modules/payment/src/Providers/PaymentServiceProvider.php b/app-modules/payment/src/Providers/PaymentServiceProvider.php
index 9fa2af7..6898f8b 100644
--- a/app-modules/payment/src/Providers/PaymentServiceProvider.php
+++ b/app-modules/payment/src/Providers/PaymentServiceProvider.php
@@ -11,6 +11,8 @@ use Modules\Payment\Factories\PaymentGatewayFactory;
use Modules\Payment\Gateways\KbzMiniAppGateway;
use Modules\Payment\Listeners\MarkBookingPaid;
use Modules\Payment\Listeners\MarkBookingRefunded;
+use Modules\Payment\Models\Payment;
+use Modules\Payment\Observers\PaymentObserver;
class PaymentServiceProvider extends ServiceProvider
{
@@ -28,5 +30,7 @@ class PaymentServiceProvider extends ServiceProvider
{
Event::listen(PaymentCompleted::class, MarkBookingPaid::class);
Event::listen(RefundProcessed::class, MarkBookingRefunded::class);
+
+ Payment::observe(PaymentObserver::class);
}
}
diff --git a/app-modules/routing/src/Models/EvRoute.php b/app-modules/routing/src/Models/EvRoute.php
index aef23b6..8e08350 100644
--- a/app-modules/routing/src/Models/EvRoute.php
+++ b/app-modules/routing/src/Models/EvRoute.php
@@ -2,6 +2,7 @@
namespace Modules\Routing\Models;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -91,4 +92,11 @@ class EvRoute extends Model
{
return $this->hasMany(RoutePricing::class, 'ev_route_id');
}
+
+ public function name(): Attribute
+ {
+ return Attribute::make(
+ get: fn (): string => $this->fromDestination->name.' → '.$this->toDestination->name,
+ );
+ }
}
diff --git a/config/booking.php b/config/booking.php
index e14a755..6129ba4 100644
--- a/config/booking.php
+++ b/config/booking.php
@@ -29,4 +29,6 @@ return [
'front_seat_max_per_booking' => env('BOOKING_FRONT_SEAT_MAX_PER_BOOKING', 1),
+ // comma-separated list of admin emails to notify on booking events
+ 'admin_emails' => explode(',', env('BOOKING_ADMIN_EMAILS', 'admin@example.com')),
];