add sms sending feat
This commit is contained in:
@@ -4,6 +4,7 @@ namespace Modules\Booking\Actions;
|
||||
|
||||
use Modules\Booking\Data\AssignDriverData;
|
||||
use Modules\Booking\Enums\BookingStatus;
|
||||
use Modules\Booking\Events\DriverAssigned;
|
||||
use Modules\Booking\Exceptions\DriverAssignmentNotAllowedException;
|
||||
use Modules\Booking\Models\Booking;
|
||||
|
||||
@@ -21,6 +22,12 @@ class AssignDriverAction
|
||||
throw DriverAssignmentNotAllowedException::notConfirmed($booking);
|
||||
}
|
||||
|
||||
if ($booking->travel_date->lt(today())) {
|
||||
throw DriverAssignmentNotAllowedException::travelDateInPast($booking);
|
||||
}
|
||||
|
||||
$isFirstAssignment = $booking->driver_name === null;
|
||||
|
||||
$booking->update([
|
||||
'driver_name' => $data->driverName,
|
||||
'driver_phone' => $data->driverPhone,
|
||||
@@ -28,6 +35,13 @@ class AssignDriverAction
|
||||
'car_model' => $data->carModel,
|
||||
]);
|
||||
|
||||
// Guards against a double-submit of the same form resulting in two
|
||||
// identical SMS notifications to the passenger — a genuine
|
||||
// reassignment always changes at least one of these columns.
|
||||
if ($booking->wasChanged(['driver_name', 'driver_phone', 'car_plate_number', 'car_model'])) {
|
||||
DriverAssigned::dispatch($booking, $isFirstAssignment);
|
||||
}
|
||||
|
||||
return $booking;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Booking\Events;
|
||||
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Modules\Booking\Models\Booking;
|
||||
|
||||
/**
|
||||
* Fired whenever AssignDriverAction sets or updates a booking's
|
||||
* driver/vehicle details — covers both the first assignment and any later
|
||||
* reassignment, since both go through the same action. $isFirstAssignment
|
||||
* lets listeners (e.g. the SMS notification) word the message differently
|
||||
* for "driver assigned" vs "driver info updated".
|
||||
*/
|
||||
class DriverAssigned
|
||||
{
|
||||
use Dispatchable;
|
||||
|
||||
public function __construct(public Booking $booking, public bool $isFirstAssignment) {}
|
||||
}
|
||||
@@ -16,6 +16,13 @@ class DriverAssignmentNotAllowedException extends RuntimeException
|
||||
);
|
||||
}
|
||||
|
||||
public static function travelDateInPast(Booking $booking): self
|
||||
{
|
||||
return new self(
|
||||
"Booking [{$booking->booking_ref}] cannot have a driver assigned because its travel date [{$booking->travel_date->toDateString()}] is in the past."
|
||||
);
|
||||
}
|
||||
|
||||
public function render(Request $request): ?JsonResponse
|
||||
{
|
||||
if ($request->expectsJson()) {
|
||||
|
||||
+1
@@ -25,6 +25,7 @@ class AssignDriverTableAction
|
||||
->icon(Heroicon::OutlinedTruck)
|
||||
->color('primary')
|
||||
->visible(fn (Booking $record): bool => $record->status === BookingStatus::Confirmed
|
||||
&& $record->travel_date->gte(today())
|
||||
&& (auth()->user()?->can('manage_bookings') ?? false))
|
||||
->schema([
|
||||
TextInput::make('driver_name')->required(),
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Booking\Listeners;
|
||||
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Modules\Booking\Events\DriverAssigned;
|
||||
use Modules\Shared\Sms\SmsService;
|
||||
|
||||
/**
|
||||
* Notifies the passenger of their driver/car details whenever a driver is
|
||||
* assigned or reassigned (domain.md — driver/vehicle assignment). Queued
|
||||
* since it's an outbound HTTP call to the SMS gateway.
|
||||
*/
|
||||
class SendDriverAssignedSms implements ShouldQueue
|
||||
{
|
||||
public function __construct(private readonly SmsService $smsService) {}
|
||||
|
||||
public function handle(DriverAssigned $event): void
|
||||
{
|
||||
$booking = $event->booking;
|
||||
|
||||
$this->smsService->send($booking->passenger_phone, $this->message($event));
|
||||
}
|
||||
|
||||
private function message(DriverAssigned $event): string
|
||||
{
|
||||
$booking = $event->booking;
|
||||
|
||||
$vehicle = trim($booking->car_model !== null
|
||||
? "{$booking->car_plate_number} ({$booking->car_model})"
|
||||
: $booking->car_plate_number);
|
||||
$route = $booking->route->fromDestination->name.' - '.$booking->route->toDestination->name;
|
||||
$mmRoute = $booking->route->fromDestination->mm_name.' - '.$booking->route->toDestination->mm_name;
|
||||
|
||||
$appName = 'BNF Express - '.config('app.name');
|
||||
$supportPhone = config('app.support_phone');
|
||||
$supportEmail = config('app.support_email');
|
||||
$contact = "Help: {$supportPhone} / {$supportEmail}\nအကူအညီလိုအပ်ပါက ဆက်သွယ်ရန်: {$supportPhone} / {$supportEmail}";
|
||||
|
||||
if ($event->isFirstAssignment) {
|
||||
$en = "Your driver has been assigned for booking {$booking->booking_ref} ({$route}). Driver: {$booking->driver_name}, {$booking->driver_phone}. Vehicle: {$vehicle}.";
|
||||
$mm = "ဘွတ်ကင် {$booking->booking_ref} ({$mmRoute}) အတွက် ယာဉ်မောင်း သတ်မှတ်ပြီးပါပြီ။ ယာဉ်မောင်း - {$booking->driver_name}, {$booking->driver_phone}။ ယာဉ် - {$vehicle}။";
|
||||
} else {
|
||||
$en = "Driver info updated for booking {$booking->booking_ref} ({$route}). Driver: {$booking->driver_name}, {$booking->driver_phone}. Vehicle: {$vehicle}.";
|
||||
$mm = "ဘွတ်ကင် {$booking->booking_ref} ({$mmRoute}) ၏ ယာဉ်မောင်းအချက်အလက်ကို ပြင်ဆင်ထားပါသည်။ ယာဉ်မောင်း - {$booking->driver_name}, {$booking->driver_phone}။ ယာဉ် - {$vehicle}။";
|
||||
}
|
||||
|
||||
return "{$appName}\n{$en}\n{$mm}\n{$contact}";
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,10 @@
|
||||
namespace Modules\Booking\Providers;
|
||||
|
||||
use Illuminate\Contracts\Auth\Access\Gate;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\Booking\Events\DriverAssigned;
|
||||
use Modules\Booking\Listeners\SendDriverAssignedSms;
|
||||
use Modules\Booking\Policies\BookingPolicy;
|
||||
|
||||
class BookingServiceProvider extends ServiceProvider
|
||||
@@ -13,5 +16,7 @@ class BookingServiceProvider extends ServiceProvider
|
||||
public function boot(Gate $gate): void
|
||||
{
|
||||
$gate->policy('Modules\Booking\Models\Booking', BookingPolicy::class);
|
||||
|
||||
// Event::listen(DriverAssigned::class, SendDriverAssignedSms::class);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user