From 5c215b4647b648903e801ffc77cec5b2c0caee83 Mon Sep 17 00:00:00 2001 From: Nyan Lin Paing <117423022+LinPaing21@users.noreply.github.com> Date: Wed, 19 Aug 2026 21:43:00 +0700 Subject: [PATCH] add admin noti email feat --- .../views/mails/new-booking-alert.blade.php | 30 +++++++++ .../payment/src/Mail/NewBookingAlert.php | 61 +++++++++++++++++++ .../payment/src/Observers/PaymentObserver.php | 35 +++++++++++ .../src/Providers/PaymentServiceProvider.php | 4 ++ app-modules/routing/src/Models/EvRoute.php | 8 +++ config/booking.php | 2 + 6 files changed, 140 insertions(+) create mode 100644 app-modules/payment/resources/views/mails/new-booking-alert.blade.php create mode 100644 app-modules/payment/src/Mail/NewBookingAlert.php create mode 100644 app-modules/payment/src/Observers/PaymentObserver.php 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')), ];